服务器端模板注入(SSTI)完全指南
作者:Xcheater
发布时间:2025年7月
来源:InfoSec Write-ups
引言
服务器端模板注入(SSTI)是一个影响重大却最常被忽视的漏洞类型。在进行安全评估时,我们往往会错过这类漏洞。本文将深入探讨该漏洞的基础知识、影响范围以及挖掘方法。
模板引擎基础
模板引擎允许使用占位符和表达式将动态内容注入静态模板。常见的模板引擎包括:
- Jinja2 (Python)
- Twig (PHP)
- Freemarker (Java)
- Mustache (JavaScript)
模板引擎的核心目的是在静态内容中展示动态内容。当应用程序接收用户名输入并显示个性化内容时,正是通过模板动态生成输出结果。
示例:Had lunch, {{ name }}!
这种方式将用户输入传递给模板并渲染内容。如果未正确处理不受信任的用户输入,将存在安全风险。
什么是服务器端模板注入?
当用户输入未经适当清理或验证直接传递到模板引擎时,恶意用户可以在服务器端模板引擎中注入并执行任意模板代码。
漏洞代码示例
|
|
这是一个Flask + Jinja2的漏洞代码片段,它从URL获取用户输入并直接传递到模板,没有任何清理或验证。
攻击者可以轻易利用此漏洞,通过控制URL中的name参数注入恶意SSTI载荷:
http://xcheater.medium.com/?name={{ 5 * 5 }}
输出结果将为25。这种漏洞可能进一步升级导致远程代码执行(RCE)。
在某些情况下,可能无法立即看到注入载荷的输出,但可能存在盲注或二阶SSTI漏洞。
SSTI的影响
该漏洞可被串联利用,导致:
- 数据泄露
- 拒绝服务
- 跨站脚本攻击
- 远程代码执行
如何识别SSTI
-
识别所有入口点:即用户可控的输入点,重点关注应用程序接收用户数据并处理显示动态内容的位置。
-
初始检测:尝试使用以下常见SSTI载荷,检查是否存在错误、数学运算或与常规数据的差异:
{{7*7}}
,${7*7}
,<%= 7*7 %>
,${{7*7}}
,#{7*7}
,{{'7'*7}}
- 如果输出为49,则存在漏洞
-
基于错误的检测:触发错误(如)通过错误消息揭示引擎类型
-
盲注SSTI:使用时间延迟(如
{{ sleep(5) }}
)或带外(OOB)载荷
利用步骤
步骤1:识别模板引擎
语法指纹识别:
{{7*'7'}}
→ Jinja2返回'7777777’(字符串),Twig返回49(数字)${"a"+"b"}
→ Mako/Freemarker返回"ab"<%= 7*7 %>
→ ERB (Ruby)返回49
泄露内置对象:
{{config}}
→ Flask配置(Python){{_self}}
→ Twig模板范围(PHP)<%= ENV.inspect %>
→ Ruby环境变量
步骤2:探索可访问内容
根据识别出的引擎类型,探索可访问的内置对象、变量、配置等:
Jinja2 (Python/Flask):
{{ config }}
→ 泄露Flask/Django配置(密钥、调试模式){{ request }}
→ 访问Flask请求对象(cookies、headers){{ url_for.__globals__ }}
→ 访问全局变量(如os
、sys
)
Twig (PHP):
{{ _self }}
→ 模板范围(暴露环境和过滤器){{ _self.env }}
→ 环境变量(如数据库凭据)
Freemarker (Java):
${.data_model}
→ 转储数据模型(传递给模板的变量)${object?api.class}
→ 访问Java对象方法(反射)
无法实现RCE的情况
即使发现SSTI,有时也无法获得RCE,原因包括:
- 模板引擎默认安全配置,阻止访问危险对象
- 应用程序运行在容器化或受限环境中
- 使用无逻辑模板引擎(如Mustache、Handlebars)
- 无服务器设置或权限最小的微服务环境
即使无法实现RCE,仍可利用SSTI读取敏感文件、执行内部SSRF攻击或干扰应用程序业务逻辑。
缓解策略
安全使用模板引擎
- 使用无逻辑模板引擎(如Mustache、Handlebars)
- 限制访问可能被滥用的内置对象(如os、sys、subprocess)
- 阻止危险函数(如eval、globals)
- 避免使用
render_template_string()
等动态编译函数
输入验证和清理
- 始终在模板中使用前验证和清理用户输入
- 转义模板相关字符(如{、}、$、<%)
- 避免将原始用户输入直接注入模板
最小权限和运行时加固
- 以最小权限运行应用程序和模板引擎
- 使用容器或沙箱隔离模板渲染过程
- 不要给模板引擎访问OS级资源或敏感环境变量的权限
Happy Hacking!
Twitter: https://twitter.com/Xch_eater