由WCTF2020 Thymeleaf分析payload形式
字数 1719 2025-08-18 11:35:46

Thymeleaf模板注入漏洞分析与利用

1. 漏洞背景

Thymeleaf是一种现代服务器端Java模板引擎,当与Spring框架结合使用时,如果处理不当可能导致模板注入漏洞。本文基于WCTF2020比赛中的Thymeleaf题目,分析其漏洞原理及多种payload形式。

2. 环境特性

  • Spring+Thymeleaf环境:当web应用基于Spring时,Thymeleaf使用SpEL表达式语言
  • 独立Thymeleaf环境:使用OGNL表达式语言

3. Thymeleaf预处理机制

Thymeleaf有一个关键特性叫做表达式预处理(Expression PreProcessing),置于__...__中的内容会被预处理:

#{selection.__${sel.code}__}

预处理结果会作为表达式的一部分继续处理。

4. 请求处理流程分析

4.1 获取View的过程

  1. DispatcherServlet处理流程

    • 定位到org.springframework.web.servlet.DispatcherServlet#doDispatch()
    • 获取ModelAndView对象的两步关键过程:
      • ha.handle()
      • applyDefaultViewName()
  2. ModelAndView的view值获取

    • 有返回值的方法:返回值作为view值
      @GetMapping("/path")
      public String path(@RequestParam String lang) {
          return "user/" + lang + "/welcome";
      }
      
    • void方法:ModelAndView的view值为null
  3. 默认ViewName处理

    • 当view为null时,会获取DefaultView
    • transformPath()处理:
      • 去掉前后/
      • .及之后内容当作扩展名并截掉
      • 因此payload后需要增加.以保证内容完整

4.2 表达式解析流程

  1. 视图渲染

    • processDispatchResult()
    • render()
    • ThymeleafView.render()
    • renderFragment()
  2. 表达式解析关键点

    • 判断viewTemplateName是否包含::
    • 调用IStandardExpressionParser.parseExpression()解析~{viewTemplateName}
    • 预处理__${}__里的内容
    • 进行第二次表达式解析
  3. 执行特点

    • 第一次处理时,只要__${}__语法正确,一定会被执行
    • 第二次解析失败会显示原viewTemplateName值,但恶意语句已执行

5. 不同场景下的Payload分析

5.1 场景一:有返回值的控制器方法

Payload形式

  • __${xxx}__
  • __${xxx}__::x

特点

  • 拼接结果为~{user/welcome}
  • 第一次解析后为~{user/xxx::/welcome}(合法语法)
  • 不需要.x也能成功

5.2 场景二:void方法

Payload形式

  • __${xxx}__::x.

特点

  • 使用path值作为view
  • 需要::后有值且最后有.(防止被截断)

5.3 场景三:无::的情况

Payload形式

  • __${xxx}__.

特点

  • 不需要::
  • 结尾需要.(防止被截断)

5.4 场景四:@ResponseBody注解

特点

  • 不能成功
  • Spring会将返回值作为响应内容而非模板

6. 通用Payload建议

  1. 有回显情况

    • __${}__::x.
  2. 无回显情况

    • 确保__${}__语法正确
    • viewTemplateName中包含::(位置不限)

7. 检测与防御建议

7.1 漏洞检测

  • 分析控制器方法是否有返回值
  • 检查是否使用@ResponseBody
  • 测试不同payload形式

7.2 防御措施

  • 避免用户输入直接进入模板解析
  • 对用户输入进行严格过滤
  • 使用最新版本的Thymeleaf和Spring框架

8. 总结

Thymeleaf模板注入漏洞的利用需要根据具体场景选择适当的payload形式。理解Spring与Thymeleaf的交互流程以及表达式解析机制是分析和利用此类漏洞的关键。在实际应用中,开发者应当注意避免不安全的模板处理方式,以防止此类漏洞的产生。

Thymeleaf模板注入漏洞分析与利用 1. 漏洞背景 Thymeleaf是一种现代服务器端Java模板引擎,当与Spring框架结合使用时,如果处理不当可能导致模板注入漏洞。本文基于WCTF2020比赛中的Thymeleaf题目,分析其漏洞原理及多种payload形式。 2. 环境特性 Spring+Thymeleaf环境 :当web应用基于Spring时,Thymeleaf使用SpEL表达式语言 独立Thymeleaf环境 :使用OGNL表达式语言 3. Thymeleaf预处理机制 Thymeleaf有一个关键特性叫做 表达式预处理 (Expression PreProcessing),置于 __...__ 中的内容会被预处理: 预处理结果会作为表达式的一部分继续处理。 4. 请求处理流程分析 4.1 获取View的过程 DispatcherServlet处理流程 : 定位到 org.springframework.web.servlet.DispatcherServlet#doDispatch() 获取ModelAndView对象的两步关键过程: ha.handle() applyDefaultViewName() ModelAndView的view值获取 : 有返回值的方法:返回值作为view值 void方法:ModelAndView的view值为null 默认ViewName处理 : 当view为null时,会获取DefaultView transformPath() 处理: 去掉前后 / 将 . 及之后内容当作扩展名并截掉 因此payload后需要增加 . 以保证内容完整 4.2 表达式解析流程 视图渲染 : processDispatchResult() render() ThymeleafView.render() renderFragment() 表达式解析关键点 : 判断viewTemplateName是否包含 :: 调用 IStandardExpressionParser.parseExpression() 解析 ~{viewTemplateName} 预处理 __${}__ 里的内容 进行第二次表达式解析 执行特点 : 第一次处理时,只要 __${}__ 语法正确,一定会被执行 第二次解析失败会显示原viewTemplateName值,但恶意语句已执行 5. 不同场景下的Payload分析 5.1 场景一:有返回值的控制器方法 Payload形式 : __${xxx}__ __${xxx}__::x 特点 : 拼接结果为 ~{user/welcome} 第一次解析后为 ~{user/xxx::/welcome} (合法语法) 不需要 .x 也能成功 5.2 场景二:void方法 Payload形式 : __${xxx}__::x. 特点 : 使用path值作为view 需要 :: 后有值且最后有 . (防止被截断) 5.3 场景三:无 :: 的情况 Payload形式 : __${xxx}__. 特点 : 不需要 :: 结尾需要 . (防止被截断) 5.4 场景四:@ResponseBody注解 特点 : 不能成功 Spring会将返回值作为响应内容而非模板 6. 通用Payload建议 有回显情况 : __${}__::x. 无回显情况 : 确保 __${}__ 语法正确 viewTemplateName中包含 :: (位置不限) 7. 检测与防御建议 7.1 漏洞检测 分析控制器方法是否有返回值 检查是否使用@ResponseBody 测试不同payload形式 7.2 防御措施 避免用户输入直接进入模板解析 对用户输入进行严格过滤 使用最新版本的Thymeleaf和Spring框架 8. 总结 Thymeleaf模板注入漏洞的利用需要根据具体场景选择适当的payload形式。理解Spring与Thymeleaf的交互流程以及表达式解析机制是分析和利用此类漏洞的关键。在实际应用中,开发者应当注意避免不安全的模板处理方式,以防止此类漏洞的产生。