发布的安全版本

作者:James Bennett 发布于 2010 年 12 月 22 日

今天,Django 团队发布了多个版本——Django 1.2.4、Django 1.1.3 和 Django 1.3 beta 1——以解决报告给我们的两个安全问题。我们敦促所有使用受影响版本的 Django 的用户立即升级。

Django 管理界面中的信息泄露

Django 管理界面,django.contrib.admin,支持通过相应模型上的字段过滤显示的对象列表,包括跨数据库级关系。这是通过在 URL 的查询字符串部分传递查找参数来实现的,并且 ModelAdmin 类上的选项允许开发人员指定将生成自动过滤链接的特定字段或关系。

一个历史上未记录且未正式支持的功能是,具有足够模型结构和这些查找参数格式知识的用户能够通过操作查询字符串动态创建有用的新过滤器。

然而,正如 Adam Baldwin 向我们报告的那样,这可能被滥用来访问超出管理员用户权限范围的信息;例如,可以访问管理员并充分了解模型结构和关系的攻击者可以构建查询字符串,这些字符串——通过重复使用 Django 数据库 API 支持的正则表达式查找——泄露敏感信息,例如用户的密码哈希。

为了解决这个问题,django.contrib.admin 现在将验证查询字符串查找参数是否仅指定正在查看的模型上的字段,或者跨应用程序开发人员使用上述预先存在的机制明确列入白名单的关系。对于任何依赖于先前插入任意查找的能力的用户来说,这是向后不兼容的,但由于此“功能”从未记录或支持过,因此我们不认为它对我们的 API 稳定性策略构成问题。但是,Django 1.3 beta 1 的发行说明——其中将包含此更改——将注意到与之前的 Django 版本的这一差异。

密码重置机制中的拒绝服务攻击

Django 的捆绑身份验证框架,django.contrib.auth,提供了允许用户重置忘记的密码的视图。重置机制涉及生成一个一次性令牌,该令牌由用户的 ID、重置请求的时间戳(转换为 36 进制整数)和从用户当前密码哈希派生的哈希组成(重置完成后将更改,从而使令牌失效)。

但是,验证此令牌的代码在尝试转换之前不会验证提供的 36 进制时间戳的长度。然后,具有足够站点 URL 配置知识和重置令牌构造方式的攻击者可以构造一个包含任意大(最多 Web 服务器支持的最大 URL 长度)36 进制整数的请求,Django 将盲目地尝试将其转换回时间戳。

正如 Paul McMillan 向我们报告的那样,尝试对越来越大的数字进行此转换所需的时间将消耗大量的服务器资源,并且许多此类同时请求将导致有效的拒绝服务攻击。进一步调查发现,密码重置代码在多个地方盲目转换 36 进制。

为了解决这个问题,django.utils.http 中的 base36_to_int() 函数现在将验证其输入的长度;对于长度超过 13 位的输入(足以对任何 64 位整数进行 36 进制编码),它现在将引发 ValueError。此外,django.contrib.auth 的默认 URL 模式现在将对相关参数实施最大长度。

受影响的版本

上面描述的两个问题都存在于以下当前支持的 Django 版本中

解决方案

已将补丁应用于 Django 主干以及 1.2 和 1.1 发布分支,这些补丁解决了上述两个问题。可以从相应的更改集中直接获取这些补丁

已发布以下新版本

包含来自 Django 主干的补丁的 Django 1.3 beta 1 也将在今天晚些时候发布。

有关安全性的常规说明

与往常一样,我们要求通过私人电子邮件将潜在的安全问题报告给 security@djangoproject.com,而不是通过 Django 的 Trac 实例或 django-developers 列表

由于即将到来的圣诞节和新年假期,我们通常在安全相关版本发布前一周通知 Django 发行商的流程有所缩短,以便在大多数 Django 用户开始休假之前发布这些版本。

如果您是或代表 Django 的第三方发行商,并且没有收到来自 Django 发行经理的通知电子邮件,请联系 james@b-list.org

返回顶部