Django紧急推送安全补丁:两大漏洞影响所有活跃版本,建议立即升级
一、事件概述
Django安全团队近日向所有维护版本推送了关键更新,一口气修掉了两个潜藏的安全隐患。这次补丁覆盖6.0.3、5.2.12和4.2.29三个稳定分支,涉及一个中等危害的拒绝服务漏洞,以及一个文件权限配置不当的低危问题。如果你手头还有基于Django的项目在跑,建议抽几分钟把环境升上去,别等出了问题再补锅。
二、Windows平台URLField拒绝服务漏洞(CVE-2026-25673)
2.1 漏洞原理
这次两个漏洞里,影响面更广的是编号CVE-2026-25673的中等漏洞。问题出在URLField表单字段的to_python()方法上,在Windows环境下,这个方法在处理输入时会调用urlsplit(),而后者内部会跑一遍NFKC Unicode归一化。
# Django URLField核心代码(漏洞版本)
from urllib.parse import urlsplit
import unicodedata
class URLField:
def to_python(self, value):
# Windows下urlsplit()会调用NFKC归一化
# 当输入为大体积特殊构造字符串时,执行时间异常拉长
if value:
return urlsplit(unicodedata.normalize('NFKC', value))
return ''
2.2 攻击演示
在Windows系统下,unicodedata.normalize遇到特定构造的大体积输入时,执行时间会异常拉长。攻击者只需往URLField里塞一段精心构造的字符串,就能让服务器CPU被Unicode归一化拖住:
# 恶意输入示例(需构造特定Unicode字符)
malicious_input = 'https://example.com/' + '𠀀' * 10000
# 正常输入处理时间:5000ms
# CPU占用率:单核100%,持续5秒以上
轻则响应变慢,重则直接卡死,典型的拒绝服务攻击入口。
2.3 修复方案
Django团队的修复思路很干脆——不再走Unicode归一化这套流程,换了一套轻量级的协议检测逻辑来判断输入合法性:
# Django 4.2.29/5.2.12/6.0.3 修复后的URLField
from urllib.parse import urlparse
class URLField:
def to_python(self, value):
if value:
# 直接使用urlparse,不再做NFKC归一化
parsed = urlparse(value)
if parsed.scheme and parsed.netloc:
return value
return ''
⚠️ 注意:如果之前依赖URLField自动处理换行符、制表符或其他控制字符,升级后需自己在验证器里补上。
三、多线程场景下umask权限泄露(CVE-2026-25674)
3.1 漏洞背景
另一个低危漏洞CVE-2026-25674,平时不起眼,但在高并发环境里真能捅娄子。Django的文件存储模块和基于文件的缓存后端,创建新文件或目录时历来依赖进程的umask来控制权限。
# 漏洞代码(Django 4.2-6.0漏洞版本)
import os
class FileSystemStorage:
def save(self, name, content):
# 问题:umask是进程级全局状态
old_umask = os.umask(0o022) # 临时修改umask
try:
# 多线程环境下,这里有竞态条件
with open(name, 'wb') as f:
f.write(content)
finally:
os.umask(old_umask)
# 危险场景:线程B创建敏感文件时,恰好被A线程改成000
3.2 修复方案
这次补丁把这个隐患掐死了:创建目录之后,直接用os.chmod()显式设置权限,不再把命运交给全局umask:
# Django 4.2.29/5.2.12/6.0.3 修复后的文件存储
import os
class FileSystemStorage:
def _save(self, name, content):
# 使用os.open并指定权限位
fd = os.open(name, os.O_WRONLY | os.O_CREAT, 0o644)
try:
os.write(fd, content)
finally:
os.close(fd)
def _makedirs(self, path):
if not os.path.exists(path):
parent = os.path.dirname(path)
if parent:
self._makedirs(parent)
os.mkdir(path)
os.chmod(path, 0o755) # 直接设置权限,不依赖umask
四、受影响版本与升级路径
补丁已经合并到主开发分支,同时向下打到了所有仍在维护的稳定版本:
| 版本系列 | 受影响版本 | 修复版本 |
|---|---|---|
| Django 6.0 | 6.0.0 - 6.0.2 | 6.0.3 |
| Django 5.2 | 5.2.0 - 5.2.11 | 5.2.12 |
| Django 4.2 | 4.2.0 - 4.2.28 | 4.2.29 |
# 使用pip升级
pip install Django==6.0.3
# 或
pip install Django==5.2.12
# 或
pip install Django==4.2.29
# 验证版本
python -c "import django; print(django.VERSION)"
⚠️ 重要提示:如果你还在用Django 4.2之前的版本,官方其实已经停止维护了,这次补丁也不会覆盖到。与其纠结要不要升大版本,不如先把业务代码兼容性测一遍,尽早切到受支持的分支上。
五、安全加固建议
除了版本升级,建议同时进行以下安全加固:
- 输入验证加强:对URLField输入添加应用层验证
- 文件权限审计:检查现有文件权限是否符合最小权限原则
- 日志监控:监控异常长的URL处理请求
- 定期更新:建立Django安全更新的及时响应机制
# 应用层URL验证示例
from django.core.validators import URLValidator
from django.core.exceptions import ValidationError
def validate_url(url):
validator = URLValidator()
try:
validator(url)
return True
except ValidationError:
return False
六、总结
本次Django安全更新修复了两个在特定场景下可能造成严重影响的安全隐患:
- CVE-2026-25673:Windows平台URLField拒绝服务漏洞(中等危害)
- CVE-2026-25674:多线程umask权限泄露(低危但不可忽视)
建议所有Django项目用户立即检查并升级到上述修复版本,同时审查代码中的URL处理逻辑和文件权限设置,确保不留安全死角。
评论列表COMMENT
- 暂时还没有人发表评论。
发表评论
文明上网,从我做起!