Django Jinja2 模版渲染漏洞

Django Jinja2 模板渲染漏洞

漏洞原理及危害

Django Jinja2 模板渲染漏洞本质上是一种 服务器端模板注入 (Server-Side Template Injection, SSTI) 漏洞。当应用程序将用户输入直接嵌入到模板中进行渲染时,若未对输入进行严格过滤和转义,攻击者便可构造恶意输入,从而在服务器端执行任意代码。

攻击流程:

  1. 用户输入: 攻击者构造恶意输入,例如 {{'os'.system('ls')}}
  2. 模板渲染: 应用程序将恶意输入直接嵌入到模板中,Jinja2 引擎在渲染模板时将恶意代码视为合法的 Python 代码并执行。
  3. 代码执行: 服务器执行攻击者注入的代码,可能导致敏感信息泄露、系统命令执行、甚至远程代码执行等严重后果。

危害:

  • 任意代码执行 (RCE): 攻击者可执行任意系统命令,控制服务器。
  • 数据泄露: 攻击者可读取敏感文件、数据库信息等。
  • 拒绝服务 (DoS): 攻击者可注入耗费资源的代码,导致服务器崩溃。
  • 权限提升: 攻击者可利用漏洞获取更高的权限。

漏洞示例

1
2
3
4
5
from django.shortcuts import render

def index(request):
name = request.GET.get('name')
return render(request, 'index.html', {'name': name})
1
<h1>Hello, {{ name }}!</h1>

如果用户输入 name={{7*7}},那么渲染后的页面将会显示 Hello, 49!。但是,如果用户输入 name={{'os'.system('ls')}},那么服务器将会执行 ls 命令,列出当前目录下的文件。

1
2
3
4
5
6
# views.py
from django.shortcuts import render

def profile(request, username):
user = get_object_or_404(User, username=username)
return render(request, 'profile.html', {'user': user})
1
2
<h1>{{ user.name }}'s Profile</h1>
<p>User-Agent: {{ request.META.HTTP_USER_AGENT }}</p>

如果攻击者构造一个请求,其中 username 参数为 {{'os'.system('ls')}},那么服务器就会执行 ls 命令,列出当前目录下的文件。

漏洞成因

  • 未对用户输入进行充分过滤: 常见的原因是直接将用户输入拼接到模板字符串中。
  • 模板引擎配置不当: 如果模板引擎的配置过于宽松,允许执行一些危险的函数,也会增加漏洞风险。
  • 业务逻辑缺陷: 在某些情况下,业务逻辑的缺陷也可能导致模板注入漏洞。

防护措施

  • 永远不要信任用户输入: 对所有用户输入进行严格的过滤和转义。
  • 使用自动转义: Jinja2 默认会对变量进行自动转义,以防止 XSS 攻击。
  • 限制模板上下文: 限制模板中可访问的变量和函数,减少攻击面。
  • 自定义过滤器: 创建自定义过滤器对输入数据进行过滤和验证。
  • 沙箱机制: 使用沙箱机制限制模板执行环境。
  • 输入验证: 对用户输入的数据类型和长度进行严格的验证。
  • 错误处理: 对于异常情况,提供友好的错误提示,避免泄露敏感信息。
  • 及时更新框架和库: 定期更新 Django 和 Jinja2,以获取最新的安全修复。

防护示例

1
2
3
4
5
6
7
from django.shortcuts import render
from django.utils.html import escape

def profile(request, username):
user = get_object_or_404(User, username=username)
safe_user_agent = escape(request.META.get('HTTP_USER_AGENT', ''))
return render(request, 'profile.html', {'user': user, 'user_agent': safe_user_agent})

Django Jinja2 模版渲染漏洞
https://chrrr1y.github.io/2024/05/15/Django Jinja2 模板渲染/
作者
Chrrr1y
发布于
2024年5月15日
更新于
2024年8月15日
许可协议