细数Django框架核心历史SQL注入漏洞(下)
字数 2026 2025-08-06 18:07:49

Django框架核心历史SQL注入漏洞分析与防护指南

概述

本文详细分析Django框架历史上出现的三个核心SQL注入漏洞(CVE-2022-28346、CVE-2022-28347、CVE-2022-34265),包括漏洞原理、影响范围、利用方式及修复方案。这些漏洞涉及Django的QuerySet API关键函数,在特定配置下可能导致SQL注入风险。

CVE-2022-28346 - annotate/aggregate/extra函数注入漏洞

漏洞描述

Django在2022年发布的安全更新修复了QuerySet的annotate()aggregate()extra()函数中存在的SQL注入漏洞。攻击者可通过精心构造的别名参数注入恶意SQL代码。

影响版本

  • Django 2.2.x < 2.2.28
  • Django 3.2.x < 3.2.13
  • Django 4.0.x < 4.0.4
  • 需使用annotateaggregateextra方法且参数可控

漏洞分析

  1. 漏洞根源

    • add_annotationadd_extra函数未对参数进行充分过滤
    • 用户可控参数直接成为self.annotations的键
    • resolve_ref函数中被取出并直接使用
  2. 关键代码路径

    • django/db/models/query.py中的aggregate方法
    • 参数经过_validate_values_are_expressions处理但未过滤
    • 最终在SQL解析阶段被直接拼接
  3. 修复方案

    • alias参数添加正则过滤
    • 限制特殊字符在注解别名中的使用

漏洞复现

  1. 环境配置

    # views.py
    from django.shortcuts import render, HttpResponse
    from .models import Collection
    from django.db.models import Count
    
    def vuln(request):
        query = request.GET.get('q')
        qs = Collection.objects.annotate(**{query: Count("name")})
        return HttpResponse(qs)
    
  2. 利用Payload

    http://127.0.0.1:8000/vuln/?q=aaaaa%22
    

CVE-2022-28347 - explain()函数注入漏洞

漏洞描述

Django修复了QuerySet的explain()函数中存在的SQL注入漏洞,攻击者可通过控制explain选项注入恶意SQL。

影响版本

  • Django 2.2.x < 2.2.28
  • Django 3.2.x < 3.2.13
  • Django 4.0.x < 4.0.4
  • 需使用explain方法且参数可控

漏洞分析

  1. 漏洞根源

    • explain_query_prefix处理用户提供的options时未充分过滤
    • PostgreSQL后端直接将选项键名拼接到SQL语句
  2. 关键代码路径

    • django/db/models/sql/compiler.py中的explain处理
    • django/db/backends/postgresql/operations.pyexplain_query_prefix方法
    • 选项键名直接写入SQL前缀
  3. 修复方案

    • 实现options内容过滤
    • 建立选项键名白名单机制

漏洞复现

  1. 环境配置

    # views.py
    from django.shortcuts import render, HttpResponse
    from .models import Collection
    import json
    
    def vuln(request):
        query = request.GET.get('q')
        query = json.loads(query)
        qs = Collection.objects.filter(name="tom").explain(**query)
        return HttpResponse(qs)
    
  2. 利用Payload

    http://127.0.0.1:8000/vuln/?q={"ANALYZE true)":"aaa"}
    

CVE-2022-34265 - Trunc/Extract函数注入漏洞

漏洞描述

Django修复了Trunc()Extract()函数中存在的SQL注入漏洞,攻击者可通过控制查询参数注入恶意SQL。

影响版本

  • Django 3.2.x < 3.2.14
  • Django 4.0.x < 4.0.6
  • 需使用Trunc()Extract()方法且参数可控

漏洞分析

  1. 漏洞根源

    • ExtractTrunc类的as_sql方法未过滤lookup_name参数
    • 参数直接传递到datetime_extract_sqldatetime_trunc_sql函数
    • 最终在else分支中直接拼接SQL
  2. 关键代码路径

    • Extract.as_sql方法
    • datetime_extract_sqldate_extract_sql函数
    • lookup_type参数直接拼接
  3. 修复方案

    • ExtractTrunc类的as_sql方法添加正则过滤
    • 限制特殊字符在查询参数中的使用

漏洞复现

  1. 利用Payload
    http://127.0.0.1:8000/?date=aaa%27
    

防护建议

  1. 通用防护措施

    • 及时升级到Django安全版本
    • 对所有用户输入进行严格验证和过滤
    • 使用Django ORM提供的参数化查询
  2. 针对特定漏洞

    • 避免直接使用用户输入作为注解别名
    • 限制explain选项的来源
    • 验证Trunc/Extract函数的参数
  3. 安全开发实践

    • 遵循最小权限原则
    • 实施输入验证和输出编码
    • 定期进行安全审计和代码审查

参考资源

  1. Django官方安全公告
  2. CVE详细描述:
  3. Django GitHub修复提交记录

通过深入理解这些漏洞的原理和利用方式,开发者可以更好地保护Django应用免受SQL注入攻击,同时提高整体应用安全性。

Django框架核心历史SQL注入漏洞分析与防护指南 概述 本文详细分析Django框架历史上出现的三个核心SQL注入漏洞(CVE-2022-28346、CVE-2022-28347、CVE-2022-34265),包括漏洞原理、影响范围、利用方式及修复方案。这些漏洞涉及Django的QuerySet API关键函数,在特定配置下可能导致SQL注入风险。 CVE-2022-28346 - annotate/aggregate/extra函数注入漏洞 漏洞描述 Django在2022年发布的安全更新修复了QuerySet的 annotate() 、 aggregate() 和 extra() 函数中存在的SQL注入漏洞。攻击者可通过精心构造的别名参数注入恶意SQL代码。 影响版本 Django 2.2.x < 2.2.28 Django 3.2.x < 3.2.13 Django 4.0.x < 4.0.4 需使用 annotate 、 aggregate 或 extra 方法且参数可控 漏洞分析 漏洞根源 : add_annotation 和 add_extra 函数未对参数进行充分过滤 用户可控参数直接成为 self.annotations 的键 在 resolve_ref 函数中被取出并直接使用 关键代码路径 : django/db/models/query.py 中的 aggregate 方法 参数经过 _validate_values_are_expressions 处理但未过滤 最终在SQL解析阶段被直接拼接 修复方案 : 对 alias 参数添加正则过滤 限制特殊字符在注解别名中的使用 漏洞复现 环境配置 : 利用Payload : CVE-2022-28347 - explain()函数注入漏洞 漏洞描述 Django修复了QuerySet的 explain() 函数中存在的SQL注入漏洞,攻击者可通过控制explain选项注入恶意SQL。 影响版本 Django 2.2.x < 2.2.28 Django 3.2.x < 3.2.13 Django 4.0.x < 4.0.4 需使用 explain 方法且参数可控 漏洞分析 漏洞根源 : explain_query_prefix 处理用户提供的options时未充分过滤 PostgreSQL后端直接将选项键名拼接到SQL语句 关键代码路径 : django/db/models/sql/compiler.py 中的explain处理 django/db/backends/postgresql/operations.py 的 explain_query_prefix 方法 选项键名直接写入SQL前缀 修复方案 : 实现options内容过滤 建立选项键名白名单机制 漏洞复现 环境配置 : 利用Payload : CVE-2022-34265 - Trunc/Extract函数注入漏洞 漏洞描述 Django修复了 Trunc() 和 Extract() 函数中存在的SQL注入漏洞,攻击者可通过控制查询参数注入恶意SQL。 影响版本 Django 3.2.x < 3.2.14 Django 4.0.x < 4.0.6 需使用 Trunc() 或 Extract() 方法且参数可控 漏洞分析 漏洞根源 : Extract 和 Trunc 类的 as_sql 方法未过滤 lookup_name 参数 参数直接传递到 datetime_extract_sql 和 datetime_trunc_sql 函数 最终在else分支中直接拼接SQL 关键代码路径 : Extract.as_sql 方法 datetime_extract_sql 和 date_extract_sql 函数 lookup_type 参数直接拼接 修复方案 : 为 Extract 和 Trunc 类的 as_sql 方法添加正则过滤 限制特殊字符在查询参数中的使用 漏洞复现 利用Payload : 防护建议 通用防护措施 : 及时升级到Django安全版本 对所有用户输入进行严格验证和过滤 使用Django ORM提供的参数化查询 针对特定漏洞 : 避免直接使用用户输入作为注解别名 限制explain选项的来源 验证Trunc/Extract函数的参数 安全开发实践 : 遵循最小权限原则 实施输入验证和输出编码 定期进行安全审计和代码审查 参考资源 Django官方安全公告 CVE详细描述: CVE-2022-28346 CVE-2022-28347 CVE-2022-34265 Django GitHub修复提交记录 通过深入理解这些漏洞的原理和利用方式,开发者可以更好地保护Django应用免受SQL注入攻击,同时提高整体应用安全性。