路径遍历 via archive.extract - CVE 2021-3281 不完整补丁
报告时间: 2025年9月5日,下午1:21 (UTC) 报告人: stackered (ID已验证) 报告对象: Django 状态: 已解决 严重性: 低 (3.7) CVE ID: CVE-2021-3281 (原), CVE-2025-59682 (新)
漏洞概述
在对历史漏洞补丁进行代码审查时,发现针对 CVE-2021-3281 的修复并不完整。该漏洞的原始修复逻辑是在 ZipArchive 和 TarArchive 类的 extract 函数中添加了防护逻辑,以确保所有文件都被提取到基础文件夹 (target_path) 之下。
原始防护代码
|
|
这段代码使用 abspath 函数获取绝对且规范化的唯一路径,然后利用 startswith 函数验证目标路径是否属于预期的基础文件夹。然而,abspath 函数会移除路径末尾的分隔符,这导致防护逻辑不足以防御部分路径遍历攻击。
漏洞原理
假设基础文件夹定义为 /var/lib/,初始文件名为 /var/library/test.txt。由于末尾的斜杠被移除,攻击者仍然可以进行部分路径遍历到另一个以相同字符开头的目录,因为以下检查会通过:
|
|
在Python命令行中执行以下代码不会引发预期的异常:
|
|
影响
这导致了一个部分路径遍历漏洞,允许攻击者在解压归档文件(tar和zip)时将文件写到基础目录之外。
交互时间线
2025年9月11日,下午3:53 (UTC)
- Django 工作人员 (nessita) 评论: 感谢报告,安全团队将进行调查,请暂时保密。
2025年9月16日,上午11:29 (UTC)
- Django 工作人员 (theorangeone) 将状态改为 “需要更多信息”: 无法复现问题,请求提供使用Django工具并展示漏洞利用的PoC。
2025年9月16日,下午1:28 (UTC)
- 报告人 (stackered) 将状态改回 “新建” 并提供PoC:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18import zipfile from django.utils.archive import * zip_path = "malicious.zip" def create_malicious_zip(): with zipfile.ZipFile(zip_path, "w") as zf: zf.writestr("/home/johnny/.ssh/authorized_keys", "ssh key\n") zf.writestr("test.txt", "Test\n") print(f"Archive {zip_path} hase been successfully created") def extract_archive(): archive = ZipArchive(zip_path) archive.extract("/home/john") if __name__ == "__main__": create_malicious_zip() extract_archive()- PoC说明: 在
/home下创建两个目录(john 和 johnny),并由运行PoC的同一用户可写。即使目标解压目录设置为/home/john,这也会在/home/johnny/.ssh/authorized_keys中添加(如果不存在则创建)攻击者的SSH密钥。
- PoC说明: 在
2025年9月18日,上午10:04 (UTC)
- Django 工作人员 (sarahvboyce) 将严重性从 中 (5.3) 更新为 低 (3.7): 攻击者必须知道用户将通过
startapp --template等在哪个目录进行解压。
2025年9月18日,上午10:09 (UTC)
- Django 工作人员 (sarahvboyce) 将状态改为 “已分类”: 确认漏洞,已申请CVE。附上了建议的缓解方案补丁 (
0001-Fixed-CVE-2025-XXXXX-Fixed-potential-partial-directo.patch),请求报告人测试。计划在10月发布包含此修复的版本,并询问是否可以用 “stackered” 署名。
2025年9月18日,下午1:21 (UTC)
- 报告人 (stackered) 评论: 审查了补丁,确认修复了问题。同意使用 “stackered” 署名。但对严重性评估为"低"持有不同意见,认为在某些场景(如请求拦截、开源应用、攻击者可控制解压目录)下风险更高,原评估为中危。
2025年9月24日,下午12:57 (UTC)
- 报告人 (stackered) 评论: 询问是否考虑根据其之前的消息修改严重性。
2025年9月24日,下午1:48 (UTC)
- Django 工作人员 (sarahvboyce) 评论: 确认已分配 CVE-2025-59682,计划10月1日发布。维持当前严重性评估。理由是
archive.extract是未公开的方法,根据安全政策通常不在漏洞评估范围内。其使用范围仅限于开发人员运行python manage.py startproject/app --template时,而非已部署的应用程序中。
2025年9月24日,下午2:08 (UTC)
- 报告人 (stackered) 评论: 感谢告知,下次会更仔细评估漏洞是否可能存在于Django项目中。
2025年10月2日,上午12:49 (UTC)
- Django 工作人员 (jacobtylerwalls) 关闭报告并将状态改为 “已解决”: 该问题已于10月1日在 Django 版本 5.2.7, 5.1.13, 和 4.2.25 中修复。
约15天前
- The Internet Bug Bounty 决定: 此报告不符合赏金奖励条件。
5天前
- 报告人 (stackered) 请求公开此报告。
- Django 工作人员 (jacobtylerwalls) 同意公开。
- 报告已被公开。
报告详情
- 报告ID: #3328367
- 弱点类型: 路径遍历
- 披露日期: 2025年11月21日,下午7:05 (UTC)
- 赏金: 无