漏洞报告 #3328367 - 通过 archive.extract 的路径遍历 - CVE 2021-3281 补丁不完整
时间线
stackered(已完成ID验证的黑客)向 Django 提交了一份报告。 2025年9月5日,下午1:21(UTC)
大家好, 在对之前的漏洞补丁进行代码审查时,我发现针对 CVE-2021-3281 的修复是不完整的。提醒一下,为了缓解该漏洞,在 ZipArchive 和 TarArchive 类的 extract 函数中添加了以下防护逻辑,以确保所有文件都在基础文件夹(target_path)下解压。
|
|
abspath 函数用于获取绝对且规范化的唯一路径。然后,利用 startswith 函数验证目标路径是否在预期的基础文件夹内。然而,abspath 函数会移除路径末尾的分隔符,这使得防护逻辑不足以防范部分路径遍历。
假设基础文件夹定义为 /var/lib/,初始文件名为 /var/library/test.txt。由于尾部斜杠被移除,攻击者仍然可以通过部分路径遍历到另一个以相同字符开头的目录,因为这能通过检查。
|
|
例如,在 Python CLI 中执行以下代码行并不会引发预期的异常。
|
|
现实世界中此类部分路径遍历漏洞的案例可以在此处找到。
影响 这导致了一个部分路径遍历漏洞,使得攻击者在解压归档文件(tar 和 zip)时可以将文件写入基础目录之外。
nessita(Django 员工) 发表评论。 2025年9月11日,下午3:53(UTC)
你好, 感谢您的报告。我们将进行调查并尽快给您回复。在此期间,请对这些信息保密。 如果您尚未查阅,请查看 Django 安全团队评估报告的方式:https://docs.djangoproject.com/en/dev/internals/security/。 请注意,完成分析可能需要几周时间。除非您发现了新的相关信息,否则无需催促安全团队。所有报告的目标都是在行业标准的 90 天内解决。 此致,Django 安全团队。
theorangeone(Django 员工) 将状态更改为 需要更多信息。 2025年9月16日,上午11:29(UTC)
感谢您的报告!但是,我们自己无法复现该问题。您能否提供一个使用 Django 工具并展示利用的 PoC?希望我们能利用它来复现并解决问题。
stackered 将状态更改为 新。 2025年9月16日,下午1:28(UTC)
当然,这里有一个使用目标 Django 函数的功能性 PoC。
|
|
在 /home 目录下创建两个目录(john 和 johnny),并由运行 PoC 的同一用户可写。 即使目标解压目录设置为 /home/john,这也会添加(如果不存在则创建)攻击者的 ssh 密钥到 /home/johnny/.ssh/authorized_keys。
sarahvboyce(Django 员工) 将严重性从中等(5.3)更新为低(3.7)。 2025年9月18日,上午10:04(UTC)
要让此攻击生效,攻击者必须知道用户将通过 startapp --template 等在哪个目录进行解压。
sarahvboyce(Django 员工) 将状态更改为 已分类。 2025年9月18日,上午10:09(UTC)
感谢您的报告和进一步的信息。拥有第二个文件对于复现问题很重要。 我们已经确认了该漏洞,并已请求 CVE。 我附上了我们提议的缓解解决方案。您能否测试一下这个补丁,以确保它能可靠地修复问题? 0001-Fixed-CVE-2025-XXXXX-Fixed-potential-partial-directo.patch (F4798484) 我们计划在一篇博客文章中提及漏洞的发现者。“stackered"可以吗?或者您希望使用其他署名方式? 包含此修复的 Django 版本目前计划于 10 月发布。在更新版本发布之前,请对此保密。 再次感谢!
附件 1 个附件 F4798484:0001-Fixed-CVE-2025-XXXXX-Fixed-potential-partial-directo.patch
stackered 发表评论。 2025年9月18日,下午1:21(UTC)
您好,
感谢您的回复。很高兴你们能够复现该问题。
是的,拥有第二个文件对于让 has_leading_dir 函数返回 False 很重要。
我审查了补丁,它确实解决了问题。
Stackered 作为署名可以,谢谢。
然而,我只是想与您分享一下我对于严重性的看法。实际上,您是对的,攻击者必须知道解压文件将被放置在哪个目录。但是,通过拦截和分析请求来猜测通常并不困难。此外,应用程序可能是开源的,在这种情况下,目录将很容易被识别。最后,在某些应用中,解压目录甚至可能由攻击者控制。正是出于这些原因,我将严重性评估为中等。
stackered 发表评论。 2025年9月24日,下午12:57(UTC)
您好,您是否考虑过根据我之前的留言修改该漏洞的严重性?
sarahvboyce(Django 员工) 发表评论。 2025年9月24日,下午1:48(UTC)
感谢您对补丁的审查。该漏洞已分配 CVE-2025-59682,计划于 10 月 1 日发布修复版本。
请继续对此保密。
关于严重性,我们维持当前的评估。
archive.extract 是一个未记录的方法,因此根据我们的安全策略,通常不在范围内:https://docs.djangoproject.com/en/5.2/internals/security/#code-under-test-must-feasibly-exist-in-a-django-project
Django 包含许多私有的、未公开的函数,这些并非其公共 API 的一部分。如果一个漏洞依赖于直接以不安全的方式调用这些内部函数,则不会被视为有效的安全问题。
但是,我们需要确保 Django 本身以安全的方式使用这些未记录的方法。这将其范围缩小到 python manage.py startproject/app --template 中使用的 archive.extract。这些是开发者在设置项目时运行的命令。它们不用于已部署的应用程序中,因此您提出的建议不适用。
stackered 发表评论。 2025年9月24日,下午2:08(UTC)
好的,谢谢您提供的信息。下次在评估漏洞是否可能存在于 Django 项目中时,我们会更加小心。
jacobtylerwalls(Django 员工) 关闭了报告并将状态更改为 已解决。 2025年10月2日,上午12:49(UTC)
此问题已于 10 月 1 日在 Django 版本 5.2.7、5.1.13 和 4.2.25 中修复。
互联网漏洞赏金计划 决定此报告不符合获得赏金的条件。 2025年11月11日,下午7:22(UTC)
我们无法在此分配金钱奖励。如果您希望获得奖励,请按照 https://hackerone.com/ibb 上的说明将漏洞提交给互联网漏洞赏金计划。
stackered 请求公开此报告。 13天前
jacobtylerwalls(Django 员工) 同意公开此报告。 13天前
此报告已公开。 13天前
报告于 2025年9月5日,下午1:21(UTC) 报告者 stackered 报告给 Django
参与者
报告 ID #3328367 状态 已解决 严重性 低 (3.7) 公开日期 2025年11月21日,下午7:05(UTC) 弱点 路径遍历 CVE ID CVE-2021-3281 赏金 隐藏 账户详情 无