当攻击者不是试图“闯进门”,而是直接在“门锁系统”内部植入恶意指令时,传统的防火墙往往防不胜防。在Java生态中,这被称为SSTI(服务器端模板注入)攻击。攻击者只需在搜索框里输入一行看似无害的“计算表达式”,就有可能直接远程控制你的服务器。
今天,我们就深度拆解Java SSTI的攻击原理与危害,并详细介绍百度云防护是如何用规则ID 4203将其挡在墙外的。
一、 什么是SSTI?核心原理深度拆解
SSTI的全称是Server-Side Template Injection,即“服务器端模板注入”。为了动态生成网页内容,现代Web应用普遍使用FreeMarker、Thymeleaf、Velocity等模板引擎。这些引擎允许开发者在HTML页面中嵌入${变量名}或{{变量名}}等占位符。
1.1 漏洞的根源:数据与指令的边界模糊
SSTI的根源在于:开发者错误地将用户的“输入数据”当作“模板指令”来处理,而不是当作纯粹的文本数据。当开发者为了“图方便”,不小心将用户的输入直接拼接或格式化到模板字符串本身,而不是作为数据变量传递时,这个极其危险的漏洞就诞生了[reference:0]。
此时,模板引擎在渲染时,会把用户输入中的特殊语法当成自己的代码来执行。
1.2 一个危险的“变量”
在Spring Boot + Thymeleaf或Freemarker的应用中,Java的模板引擎功能极其强大,能够通过表达式(Expression Language, EL)直接调用Java底层对象。也就是说,攻击者可以在${...}中写入调用java.lang.Runtime类的代码。
Runtime.getRuntime().exec(“whoami”) 这个原本只存在于Java代码深处的指令,如果被直接写进模板变量,服务器会忠实地执行它,然后将结果返回给页面。
攻击链路:
- 污染入口:攻击者在搜索框或URL参数中提交
Hello ${7*7}。 - 触发渲染:服务端将攻击者的输入当成了模板引擎的解析语法(例如直接拼接进
return路径,或没有对变量进行严格转义)。 - 解析执行:模板引擎解析时,将
7*7当成表达式计算为49,拼接到输出中。 - 测试成功:页面输出了
Hello 49,确认SSTI漏洞存在。
至此,攻击者已经实现了代码执行,可以开始提权、窃取数据或植入后门。
二、 为什么SSTI是Java应用的头号“隐形杀手”?
SSTI的危害不在于它多难触发,而在于它一旦被利用,造成的后果往往是毁灭性的:
- 远程代码执行 (RCE):攻击者可以直接在服务器上执行任意系统命令,比如
ls、whoami,甚至是下载挖矿脚本。以FreeMarker为例,攻击者利用freemarker.template.utility.Execute等内置对象即可执行系统命令[reference:1]。 - 服务器完全沦陷:拿到服务器权限后,攻击者可以读取数据库配置文件、拖走整个数据库、篡改网站页面、植入长期后门。
- 横向渗透:沦陷的服务器成为攻击者进入企业内网的“桥头堡”,进而攻击其他内部系统。
三、 Java生态中SSTI的典型攻击场景
在Java生态中,SSTI高危漏洞主要集中在Freemarker和Thymeleaf两大主流模板引擎上。
3.1 Thymeleaf:若依系统SSTI到RCE的经典案例
国内极流行的Java权限管理系统RuoYi(若依)曾爆出过Thymeleaf模板注入漏洞[reference:2]。当攻击者访问/monitor/cache/getNames等接口,控制fragment参数时,可以注入恶意表达式:
__${T(java.lang.Runtime).getRuntime().exec("whoami")}__::.x
服务器收到该请求后,会直接执行whoami命令,将服务器用户身份泄露给攻击者,后续即可直接上传Webshell或执行反弹Shell[reference:3]。
3.2 Freemarker:CVE-2026-22244等真实案例
Freemarker的Execute和ObjectConstructor内置对象是SSTI攻击的重灾区。攻击者一旦控制了邮件模板内容或配置项,就能注入恶意FreeMarker指令,执行任意Java代码,甚至拿下整个服务器的控制权[reference:4]。
四、 为什么传统的WAF难以拦截SSTI?
对于这类复杂的、上下文相关的注入攻击模式,传统的WAF识别能力极其有限,主要原因有三:
- 正常与异常的边界模糊:
${7*7}这样的payload,在业务上可能是一次正常的“参数传递”,在不了解上下文语意的情况下,极易误报或漏报。 - 高可变形性:攻击者可以使用Java反射、字符串拼接、Base64编码、Unicode混淆等多种方式绕过简单的关键词匹配,生成的载荷每次都不同。
- 缺乏深层语义分析:常规WAF主要做HTTP头的特征匹配和频次分析,很少具备“识别并解析Java模板引擎语法树”的能力。
五、 百度云防护如何“看穿”SSTI攻击?
从百度云防护的内置规则库可以看到,专门有一条规则用于检测Java高危SSTI攻击:
| 规则名称 | 规则ID | 风险等级 | 防护类型 | 规则描述 |
|---|---|---|---|---|
| Code_exec.Java_Danger_S… | 4203 | 高风险 | 代码执行 | 检测高危的Java SSTI攻击行为 |
这条规则的拦截原理是:看穿语法,而非匹配特征。
5.1 深度语义解析:识别模板引擎的“潜台词”
普通的WAF看到T(java.lang.Runtime).getRuntime().exec("..."),只会检测关键词。而百度云防护的Java语法解析引擎能够模拟服务器端的渲染逻辑,精准识别出:
- Thymeleaf模板中的
${...}表达式执行 - Freemarker中对
Execute和ObjectConstructor等危险内置对象的调用[reference:5] - Velocity模板中通过
$class.inspect()方法进行反射调用的攻击模式
5.2 多层解码与混淆还原
攻击者常用的编码混淆手段(如__包裹、\u转义、十六进制编码、嵌套Base64),在百度云防护面前几乎全部失效。WAF在检测前会进行多层解码,还原出恶意指令的真实意图,再进行拦截判断。
5.3 JA4指纹与IP情报的联合分析
对于自动化SSTI扫描工具,百度云防护的JA4指纹识别可以锁定工具特征。即使攻击者不断更换IP和UA,只要其利用的恶意代码生成框架不变,就会触发针对特定JA4指纹的自动封禁。同时,结合IP动态情报库,识别攻击者常用的代理IP、云服务IP等,多维度阻断攻击源头。
5.4 低误报与高检出
正常业务中几乎不会使用T(java.lang.Runtime).getRuntime().exec("...")这样的高危表达式。规则经过海量真实流量训练,在确保高检出的同时,误报率极低,保障正常业务不受影响。
六、 如何启用百度云防护规则4203?
如果你已经接入百度云防护,只需两步:
- 登录百度云防护控制台 → 防护配置 → Web防护 → 内置规则
- 搜索规则ID 4203,确认状态为“开启”,动作为“拦截”
(建议先设为“观察”模式运行几天,确认无误后再改为“拦截”)
七、 主机吧总结:从“被动补漏”到“主动免疫”
Java SSTI的高危漏洞让无数依赖于FreeMarker、Thymeleaf等模板引擎的应用暴露在RCE的风险之下。传统的WAF在如此复杂的上下文注入面前,往往力不从心。
百度云防护凭借其深度Java语义分析引擎和强大的反混淆能力,实现了对“表达式注入”从“字符串匹配”到“语法逻辑识别”的跨越。当攻击者还在试图用${7*7}探路时,百度云防护早已看穿了他的意图,并将其精准拦截在门外。
如果你还不确定自己的Java应用是否存在SSTI风险,或者想为网站加上一道“智能免疫”的防线,欢迎联系主机吧。我们提供免费安全评估和配置指导,帮你在代码层和网络层同时构筑坚实的防御体系。
主机吧 | 百度云防护官方合作伙伴
提供WAF接入、高防CDN、高防IP、高防服务器、SSL证书一站式服务
让每一次表达式注入都无处遁形,让每一台Java服务器都稳如磐石。


