Django 1.2.5 版本发行说明
欢迎来到 Django 1.2.5 版本!
这是 Django 1.2 系列中的第五个“修复错误”的版本,提高了 Django 1.2 代码库的稳定性和性能。
除四个例外外,Django 1.2.5 保持了与 Django 1.2.4 的向后兼容性。它还包含了许多修复和其他改进。对于当前使用或针对 Django 1.2 的任何开发或部署,建议升级到 Django 1.2.5 。
有关 1.2 分支的新功能、向后不兼容性和已弃用功能的详细信息,请参阅 Django 1.2 版本发行说明。
不向后兼容的变更
AJAX 请求的 CSRF 例外
Django 包含一个 CSRF 保护机制,它通过在传出的表单中插入一个令牌来实现。然后,中间件在表单提交时检查令牌的存在,并对其进行验证。
在 Django 1.2.5 之前,我们的 CSRF 保护对 AJAX 请求做了一个例外,基于以下原因:
- 许多 AJAX 工具包在使用 XMLHttpRequest 时会添加一个 X-Requested -With 头部。
- 浏览器对于 XMLHttpRequest 具有严格的同源策略。
- 在浏览器的上下文中,只有使用 XMLHttpRequest 才能添加这种自定义头部。
因此,为了方便使用,我们基于 X-Requested-With 头部,对看起来是 AJAX 请求的请求没有应用 CSRF 检查。 Ruby on Rails Web 框架也有类似的例外情况。
最近,Google 的工程师向 Ruby on Rails 开发团队的成员们提醒了一种结合浏览器插件和重定向的技术,可以允许攻击者在向任何网站发出请求时提供自定义的 HTTP 头信息。这可以使伪造的请求看起来像是 AJAX 请求,从而破坏了 CSRF 保护机制,因为它信任 AJAX 请求具有同源性质。
Rails 团队的 Michael Koziarski 向我们提出了这个问题,我们能够制作出一个概念验证,证明了 Django 的 CSRF 处理也存在同样的漏洞。
为了解决这个问题,Django 现在将对所有请求应用完整的 CSRF 验证,无论它们看起来是否来自 AJAX 。从技术上讲,这是不兼容的,但在这种情况下,安全风险被认为超过了兼容性问题。
此外,Django 现在将接受自定义 HTTP 头 X-CSRFTOKEN 中的 CSRF 令牌,以及表单提交本身中的令牌,以便与流行的 JavaScript 工具包一起使用,这些工具包允许在所有 AJAX 请求中插入自定义头。这样做是为了方便使用。
请参阅 CSRF 文档中的示例 jQuery 代码,该代码演示了这个技巧,确保您查看的是适用于您的 Django 版本的文档,因为一些较旧版本的 Django 需要不同的确切代码。
FileField 不再删除文件
在较早的 Django 版本中,当删除包含 FileField 的模型实例时,FileField 会自行从后端存储中删除文件。这为几种潜在严重的数据丢失情况敞开了大门,包括回滚的事务和不同模型上的字段引用相同的文件。在 Django 1.2.5 中,FileField 将永远不会从后端存储中删除文件。如果需要清理孤立的文件,您需要自行处理(例如,使用一个自定义的管理命令,可以手动运行或通过 cron 定期运行)。
在测试中使用自定义 SQL 加载初始数据
Django 提供了自定义 SQL 钩子作为将手工编写的 SQL 注入到数据库同步过程中的一种方式。这个自定义 SQL 的一个可能用途是将数据插入到数据库中。如果您的自定义 SQL 包含 INSERT
语句,那么这些插入操作将在每次数据库同步时执行。这包括在运行测试套件时创建的任何测试数据库的同步。
然而,在测试 Django 1.3 的过程中,发现这个功能从未完全按照宣传的那样工作。当使用不支持事务的数据库后端或使用 TransactionTestCase 时,使用自定义 SQL 插入的数据在测试过程中将不可见。
不幸的是,要纠正这个问题,没有办法不引入向后不兼容性。与其让通过自定义 SQL 插入的初始数据处于不确定的状态,Django 现在强制执行一个策略,即通过自定义 SQL 插入的数据在测试期间将 不 可见。
这个更改只影响测试过程。您仍然可以使用自定义 SQL 在 syncdb
进程的一部分中将数据加载到生产数据库中。如果您需要在测试条件下存在数据,您应该使用 测试固件 来插入它,或者使用您的测试用例的 setUp()
方法。
ModelAdmin.lookup_allowed 签名已更改
Django 1.2.4 引入了一个名为 lookup_allowed
的方法,用于在 ModelAdmin
上处理一个安全问题(changeset [15033])。尽管这个方法从未被文档化,但似乎有一些人已经重写了 lookup_allowed
,尤其是为了应对该 changeset 引入的回归问题。虽然这个方法仍然未被文档化并且未标记为稳定,但了解该函数的签名已发生变化可能会有所帮助。