服务器端模板注入的幕后工作原理
当用户输入直接嵌入到模板引擎中,且未经适当的过滤或隔离进行评估时,就会发生服务器端模板注入。这会创建一个 SSTI 漏洞,允许攻击者注入特制的 SSTI 有效载荷(例如, {{7*7}} Jinja2 中的 SSTI 负载(在 Jinja2 中)会被引擎评估,从而实现从数据泄露到服务器上下文中任意代码执行的所有攻击。由于不同的模板引擎公开不同的对象和 API,SSTI 负载因平台而异,但具有相同的危险性:它们允许不受信任的输入逃脱预期的渲染流程并在应用程序的运行时执行,如果不加以控制,通常会导致完全远程代码执行或横向移动。
Jinja2 中的最小漏洞示例
from flask import request, render_template_string
@app.route("/hello")
def hello():
name = request.args.get("name", "world")
# ❌ Vulnerable: directly rendering user input
return render_template_string("Hello " + name)
如果用户发送 ?名称={{7*7}},应用程序将对其进行评估,返回 您好49。这是教科书式的 SSTI 漏洞。
Twig 中的最小漏洞示例
// ❌ Vulnerable Twig usage
$template = $twig->createTemplate("Welcome " . $_GET['user']);
echo $template->render([]);
攻击者可以注入 SSTI 有效载荷,例如 {{7*7}} 来证明代码的执行。 危险:简单的注入可能会升级为读取文件、执行操作系统命令或深入基础设施。
真实世界漏洞:触发远程代码执行的 SSTI 有效负载
一旦存在 SSTI 漏洞,攻击者就会尝试从概念验证数学转向全面 RCE的. 不同的模板引擎对有效载荷的处理方式不同。
Jinja2 有效载荷
- {{7*7}} → 算术执行
- {{config.items()}} → 泄露服务器配置。
- {{ ”.__class__.__mro__[2].__subclasses__() }} → RCE 路径
速度有效载荷
- #设置($x=”7″)${x} → 注射旁路
- #设置($a=$class.inspect(“java.lang.Runtime”)) → 直接运行时访问
Twig 有效载荷
- {{7*7}} → 算术
- {{app.request.server.all}} → 环境变量
- {{_self.env.registerUndefinedFilterCallback(‘system’)}} → 代码执行
这些 SSTI 有效载荷展示了不同引擎中的相同漏洞如何导致不同的 利用路径, 但它们总是很危险。
服务器端模板注入的隐藏位置 CI/CD驱动的应用程序
服务器端模板注入不仅仅是 Web 应用程序的风险;它还出现在 现代 CI/CD pipelines 了。 典型的藏身之处包括:
- 掌舵图 在 Kubernetes 中,模板值是动态呈现的
- 电子邮件模板 连接用户控制的输入
- Dashboards 将查询字符串或配置数据注入模板
- DevOps 脚本 使用模板引擎生成 HTML/Markdown。
计费示例:
# ❌ Insecure Helm values with user input
configMap:
appMessage: "{{ .Values.message }}"
If.Values.message 来自不受信任的输入,它会在你的部署中引入服务器端模板注入 pipeline 本身。
使用更安全的模板模式和静态分析预防 SSTI
缓解 SSTI 漏洞需要更好的编码模式和早期检测。
安全模式
- ❌不要使用 render_template_string 或同等学历
- ✅ 使用预定义的模板文件并传递已清理的变量
- ✅ 沙盒模板引擎(如果可用)
- ✅ 在渲染之前验证并转义用户输入
不安全与安全的 cookie 处理(相关输入风险)
# ❌ Insecure: session cookie without flags
response.set_cookie("session", token)
# ✅ Secure: session cookie hardened
response.set_cookie("session", token, httponly=True, secure=True, samesite="Strict")
开发人员迷你清单
- 永远不要直接渲染原始用户输入
- 在支持的情况下使用沙盒模板
- 清理并验证所有模板变量
- 避免自定义模板评估器
- 扫描二维码 render_template_string 或字符串连接模式
静态分析 并且 linters 可以在有风险的构造进入生产之前对其进行标记。
在 DevSecOps 中嵌入 SSTI 检查 Pipelines
尽早发现服务器端模板注入比事后修复更经济、更安全。DevSecOps 团队应该将检查嵌入到 pipelines:
- Commit hooks: 拒绝 commit具有危险功能的(render_template_string)
- 静态分析器:扫描模板代码中的服务器端模板注入风险
- 依赖项验证:标记具有已知 SSTI 漏洞的过时模板引擎
- Pipeline 盖茨:块合并直到 SSTI 检查通过
通过将 SSTI 有效载荷检测作为 CI/CD,就可以防止可利用的代码被发送。
不要让服务器端模板注入进入你的堆栈
单个服务器端模板注入可能会从数学技巧升级({{7*7}}) 到完全远程代码执行。SSTI 漏洞不仅出现在 Web 应用程序中,还出现在 CI/CD pipelines、Helm 图表和电子邮件模板。
关键外卖
- 永远不要将原始用户输入呈现到模板中
- 验证并清理所有动态变量
- 不同的引擎(Jinja2、Velocity、Twig)有不同的 SSTI 有效载荷,但都可以被武器化
- 使用静态分析和快速失败门 pipelines
- 定期审核堆栈中的模板
像工具一样 西吉尼 帮助团队检测不安全的模板使用情况、阻止 SSI 漏洞并在整个过程中实施安全实践 pipeline和依赖项。 在 DevSecOps 中,将 SSTI 有效载荷视为顶级风险至关重要,因为一次注入 pipeline 或应用程序可能会危及您的整个环境。





