FreeMarker 是 Java 生态中使用最广泛的模板引擎之一,也是服务器端模板注入(SSTI)的重灾区。攻击者一旦在邮件模板、配置项或用户输入中注入恶意表达式,就可以在服务器上执行任意命令,窃取数据、植入后门甚至完全控制主机。百度云防护内置规则 Code_exec.freemarker_ssti_exec.A(规则ID 4194)通过深度语法解析与危险对象调用检测,在攻击抵达业务系统前精准拦截。
一、 什么是 FreeMarker SSTI?
1.1 SSTI 漏洞原理
服务器端模板注入(SSTI)是指当应用程序将用户输入的字符串直接拼接到服务器端模板(如邮件模板、页面模板)中进行渲染时,用户输入中包含的模板语法被模板引擎当作指令执行。
FreeMarker 模板引擎中,${...} 和 #{...} 语法用于计算表达式并输出结果。正常场景下,用户输入的文本应当被当作纯文本处理,但如果开发者直接将其放入模板表达式中,攻击者就可以注入恶意表达式,导致任意代码执行。
1.2 攻击验证
发送 ${7*7} 到注入点,如果服务器返回 49,说明应用程序使用 FreeMarker 模板引擎且存在 SSTI 漏洞。攻击者随后可以将表达式升级为调用 Java 危险对象的 payload,直接执行系统命令。
1.3 FreeMarker 的脆弱性
FreeMarker 允许通过内置对象创建任意 Java 类实例并调用其方法,攻击者常用以下两种方式执行系统命令:
| 利用方式 | 关键 API / 内置对象 | 作用 |
|---|---|---|
| Execute 对象 | freemarker.template.utility.Execute | 直接执行系统命令 |
| ObjectConstructor 对象 | freemarker.template.utility.ObjectConstructor | 实例化任意 Java 类,进而调用 Runtime.exec() |
二、 真实案例:CVE-2026-22244
2026 年 1 月,OpenMetadata 平台曝出 SSTI 漏洞 CVE-2026-22244。由于 FreeMarker 邮件模板中对用户可控的输入未做充分过滤,持有管理员权限的攻击者通过注入恶意模板指令实现了远程代码执行。攻击路径如下:
- 登录 OpenMetadata 后台(需管理员权限)。
- 修改邮件模板配置,注入恶意 FreeMarker 表达式。
- 表达式通过
Execute或ObjectConstructor调用系统命令。 - 邮件发送时触发模板渲染,命令在服务器上执行。
漏洞危害:攻击者可以完全控制底层服务器,窃取敏感数据、植入后门或横向渗透内网。
OpenMetadata 在 1.11.4 版本中通过升级依赖组件修复了该漏洞。
三、 漏洞危害总结
FreeMarker SSTI 漏洞的 CVSS 评分通常为 7.5–9.8,属于高危至严重级别。
| 危害类型 | 具体后果 |
|---|---|
| 远程代码执行 | 执行任意系统命令(如 id、curl 下载木马、nc 反弹 Shell) |
| 数据泄露 | 读取数据库配置文件、源代码、用户凭证 |
| 服务器失陷 | 写入 Webshell,完全控制服务器 |
| 内网横向移动 | 以失陷服务器为跳板攻击内网其他系统 |
| 持久化后门 | 植入挖矿程序、勒索软件或长期后门 |
四、 百度云防护如何拦截 FreeMarker SSTI?
从百度云防护内置规则库可以看到:
| 规则名称 | 规则ID | 风险等级 | 防护类型 | 规则描述 |
|---|---|---|---|---|
| Code_exec.freemarker_ssti_exec.A | 4194 | 高风险 | 代码执行 | 检测 Freemarker 模板注入导致的命令执行攻击 |
该规则基于百度安全团队对 FreeMarker SSTI 攻击手法的深度分析,通过以下机制实现精准拦截:
4.1 深度语法解析
规则不依赖简单的关键词匹配,而是解析 HTTP 请求中的表达式语法,能够识别:
${...}、#{...}等 FreeMarker 表达式边界符- 类访问语法和对象调用模式
- 对
Runtime.exec()、ProcessBuilder等危险 Java 类的调用链
4.2 识别危险内置对象
规则内置了 FreeMarker 中可用于命令执行的危险对象特征库:
freemarker.template.utility.Execute(直接执行系统命令)freemarker.template.utility.ObjectConstructor(实例化任意 Java 对象)freemarker.template.utility.JythonRuntime等?new()内置函数动态实例化类eval字符串动态求值
4.3 多层解码,还原混淆载荷
攻击者常用的混淆手段在规则 4194 面前全部失效:
- URL 编码:
%24%7B...%7D自动解码 - 嵌套表达式:
${"freemarker.template.utility.Execute"?new()("calc")}完整还原 - Unicode 转义:
\u0024\u007B...自动解码 - 动态字符串拼接,同样会被还原为完整调用链
4.4 低误报设计
正常业务中极少出现 freemarker.template.utility.Execute 或 ?new() 构造系统命令的表达式。规则经过海量真实流量训练,误报率极低。如有合法需求,可通过白名单放行。
五、 如何启用规则 4194?
如果已接入百度云防护 WAF,只需两步:
- 登录控制台 → 防护配置 → Web防护 → 内置规则
- 搜索规则 ID 4194,确认状态为“开启”,动作为“拦截”
(建议首次设为“观察”模式运行 1-2 天,确认无误后再改为“拦截”)
基础防护规则默认开启,业务接入 WAF 后即自动获得防护,无需额外配置。
六、 进阶防护:JA4 指纹精准锁定攻击工具
攻击者可能不断变换 IP、UA,甚至尝试混淆 payload,但其使用的攻击工具(脚本、框架)的 JA4 指纹通常固定。百度云防护支持 JA4 指纹匹配,可从“识别攻击特征”升级为“识别攻击工具”。
JA4 vs JA3
JA4 是 JA3 的升级版,抗混淆性更强,能精准识别使用特定库或配置的恶意工具。
| 维度 | JA3 指纹 | JA4 指纹 |
|---|---|---|
| 抗混淆 | 顺序改变即变,易被篡改 | 基于原始字节哈希,难以伪装 |
| 区分度 | 中等 | 结合应用层+网络层特征,更独特 |
配置步骤
- 在 攻击详情 中筛选恶意请求,复制 JA4 指纹
- 进入 自定义规则 → 添加规则
- 匹配条件选择 JA4 → 等于多值之一,粘贴指纹
- 处置动作选择 拦截
七、 开发人员如何从源头修复?
除依赖 WAF 外,开发者也应遵循以下安全编码规范:
- 禁止用户输入进入模板表达式:永远不要将用户输入直接放入
${...}中。使用数据模型(Model)传递用户数据。 - 配置 TemplateClassResolver:设置为
ALLOWS_NOTHING_RESOLVER,禁用ObjectConstructor、Execute等危险类。 - 升级 FreeMarker 版本:新版本对类加载有更严格限制。
- 启用模板沙箱:限制模板可访问的 Java 类和 API。
- 输入验证:对用户输入的模板内容进行严格校验。
八、 总结
FreeMarker 模板注入漏洞是 Java 应用中高危但易被忽视的安全风险。攻击者通过一行恶意表达式,即可让服务器执行任意系统命令。百度云防护规则 4194(Code_exec.freemarker_ssti_exec.A)通过深度语法解析、危险对象调用检测、多层解码,精准识别并拦截各类 SSTI 攻击,配合 JA4 指纹识别形成纵深防御。
如果你还不确定自己的 Java 应用是否存在 FreeMarker 注入风险,或想为网站加上一道主动防御屏障,欢迎联系主机吧。我们提供免费安全评估和配置指导。
主机吧 | 百度云防护官方合作伙伴
提供 WAF 接入、高防 CDN、高防 IP、高防服务器、SSL 证书一站式服务
让每一次模板注入都无处遁形,让每一台 Java 服务器都稳如磐石。


