发布的安全版本
今天,Django 团队发布了多个版本——Django 1.3.2 和 Django 1.4.1——以解决报告给我们的安全问题。
鼓励所有用户立即升级 Django。
身份验证视图中的跨站脚本攻击
Django 身份验证框架中提供的login()
和 logout()
视图使用了常见的“POST-重定向-GET”模式;可以使用可配置的查询字符串参数来指定成功提交后要重定向到的位置。目前,这些视图执行基本验证以确保重定向位置未指定不同的域。
但是,此验证不会检查目标 URL 的方案;利用此知识,攻击者可以例如构建一个data:
方案 URL,该 URL 将执行 JavaScript。
已知某些浏览器目前可以防止此问题:特别是 Google Chrome 明确禁止重定向到data:
方案 URL。但是,其他几个主要浏览器确实允许此类重定向。
在仔细考虑了此问题后,我们已决定最安全的做法是稍微破坏向后兼容性。虽然可以通过在相关视图中进行更严格的验证来实现临时缓解措施,但根本问题在于 Django 的 HTTP 响应类,它们目前没有执行任何重定向目标的验证。一些主要浏览器已经不允许在重定向中使用某些 URL 方案这一事实表明,此更改的影响可能很小。
因此,尽管会破坏 API 兼容性,但仍将进行以下更改
django.http.HttpResponseRedirect
和django.http.HttpResponsePermanentRedirect
现在是公共基类django.http.HttpResponseRedirectBase
的子类。- 该基类定义了一个允许的 URL 方案的显式白名单。尝试使用不在白名单中的方案的 URL 实例化重定向将引发异常
django.core.exceptions.SuspiciousOperation
,该异常已在 Django 代码库的其他部分用于类似目的(例如,警告可能存在会话篡改)。
除非发出重定向的最终用户代码显式要求重定向到不受支持的方案,或者从用户提供的参数中接受目标 URL,否则它不太可能受到影响。
在第一种情况下,对适当的重定向类(对于状态代码 302 为HttpResponseRedirect
,对于状态代码 301 为HttpResponsePermanentRedirect
)进行子类化并覆盖allowed_schemes
列表就足够了。allowed_schemes
的默认值为['http', 'https', 'ftp']
。
在后一种情况下,接受用户提供参数的代码可以尝试实例化重定向,捕获SuspiciousOperation
异常,并在需要时回退到备用位置。
目前,Django 的身份验证视图将使此异常未捕获。这意味着如果/当引发该异常时,站点管理员将收到错误报告。在允许 Django 用户观察行为并判断其暴露于潜在问题的程度一段时间后,未来的 Django 版本可能会开始捕获此异常。
图像验证中的拒绝服务攻击
Django 的表单系统包括用于处理文件上传的字段类型,包括用于上传图像的字段类——django.forms.ImageField
——它可以执行一些图像格式验证。
该验证的一部分涉及使用 Python Imaging Library (PIL) 提供的例程检测损坏的图像文件。
但是,目前在 Django 中存在的检查容易受到攻击,因为它将读取整个图像文件,包括根据需要解压缩压缩格式。可以很容易地构建一个合理大小的文件,当以这种方式解压缩时,该文件会增长到巨大的尺寸,消耗可用内存并提供执行拒绝服务攻击的能力。
为了缓解这种情况,图像验证现在将使用 PIL 的Image.verify()
方法,该方法执行一些验证检查,但不解压缩或读取整个图像文件。
通过 get_image_dimensions() 导致拒绝服务攻击
Django 的图像处理工具还包括用于确定图像尺寸的辅助方法。目前,此过程涉及从文件开头读取 1024 字节的块,并传递给 PIL 以确定尺寸;如果提供的数据不足,则会继续读取 1024 字节的块,直到 PIL 能够返回明确的答案。
虽然这对于在其标题中存储足够信息以确定尺寸的图像格式效果很好,但对于不存储足够信息的格式,它会导致大量的读/处理周期。特别是,较大的 TIFF 图像可能需要数万次这样的循环,从而占用或超时工作进程/线程,并消耗足够的服务器资源以导致有效的拒绝服务攻击。
为了缓解这种情况,正在更改确定图像尺寸的算法;初始尝试仍将使用 1024 字节的块,但每次后续读取块的大小将加倍。测试表明,这将处理 TIFF 文件的时间减少了几个数量级。
受影响的版本
上述问题存在于以下版本的 Django 中
- Django 开发主分支
- Django 1.4
- Django 1.3
解决方案
已将补丁应用于 Django 的开发主分支以及 1.4 和 1.3 发布分支,这些补丁解决了上述三个安全问题。补丁可以直接从以下更改集中获取
- 开发主分支:提交 用于重定向问题,提交 用于图像验证问题,以及提交 用于图像尺寸问题。
- Django 1.4:提交 用于重定向问题,提交 用于图像验证问题,以及提交 用于图像尺寸问题。
- Django 1.3:提交 用于重定向问题,提交 用于图像验证问题,以及提交 用于图像尺寸问题。
已发布以下新版本
- Django 1.4.1(下载 | 校验和)
Django 1.3.2(下载 | 校验和)请改用Django 1.3.3
由于 Django 的开发分支目前处于预发布 alpha 状态,因此强烈建议用户不要从该分支运行生产部署;但是,如果您目前正在这样做,则敦促您立即升级到最新的 HEAD,其中包含上述补丁。
鸣谢
确定图像尺寸的问题是由 Jeroen Dekkers 报告给我们的。图像验证问题是由 Django 的 Trac 中的一位用户作为常规错误报告的。重定向问题是由一位选择保持匿名的消息来源报告的。
这些问题的已知状态
Django 团队已收到信息,表明重定向问题的知识已超出最初报告者,并且可能当前或很快会被拥有该知识的人员利用。如上所述,图像验证问题最初是报告给 Django 的公共错误跟踪器。
因此,我们再次敦促所有受影响版本的 Django 用户立即升级。
关于安全的一般说明
与往常一样,我们要求通过私人电子邮件将潜在的安全问题报告给security@djangoproject.com
,而不是通过 Django 的 Trac 实例或 django-developers 列表。
如果您是或代表 Django 的第三方分销商,并且未从 Django 发布管理员处收到有关此公告的通知电子邮件,请联系james@b-list.org
。