安全版本发布和安全公告

作者:Daniele Procida 和 Tim Graham 发表于 2015年3月9日

根据我们的安全发布策略,Django团队发布了多个版本——Django 1.7.6 和 Django 1.8b2。这些版本现已在 PyPI 和我们的下载页面上提供。这些版本修复了 Django 管理界面中的一个安全问题。我们鼓励所有 Django 用户尽快升级。Django 主分支也已更新。如果您使用的是早于 1.7 的 Django 版本,则管理界面中的安全问题不会影响您,但下面有一个重要的公告,关于您的代码中可能存在的类似漏洞。

通常情况下,我们在发布安全版本时会预先通知某些关键组织,但不幸的是,在这种情况下,漏洞被公开披露,迫使我们在没有采用通常流程的情况下发布版本。

问题:通过中的属性进行 XSS 攻击ModelAdmin.readonly_fields

Django 管理界面中的ModelAdmin.readonly_fields 属性允许显示模型字段和模型属性。虽然前者已正确转义,但后者未经转义。因此,不受信任的内容可能会注入到管理界面中,从而为 XSS 攻击提供了一个利用途径。

在这个漏洞中,在readonly_fields中使用的每个非模型字段的模型属性(例如 @property)即使该属性未标记为安全,也将无法转义。在这个版本中,自动转义现在已正确应用。

此问题已分配标识符 CVE-2015-2241。

公告:从 Python 代码调用模板过滤器时的 HTML 转义

上面描述的漏洞是由管理员使用linebreaksbr函数造成的,该函数在模板之外使用时默认情况下不会转义其输出。

来自django.template.defaultfilters 的其他输出 HTML 的函数也存在这种行为

  • join
  • linebreaksbr
  • linebreaks_filter
  • linenumbers
  • unordered_list
  • urlize
  • urlizetrunc

在 1.8b2 之前的版本中,它们使用autoescape=None作为默认参数。这意味着当直接从 Python 代码调用这些函数时,输入将被标记为安全,但实际上并未转义,从而创建了一个 XSS 攻击途径。

我们在 1.8b2+ 中通过将此选项的默认值更改为True来修复此问题。这确保了默认情况下安全的行为,并有助于防止将来出现类似情况。此外,编写自定义模板过滤器的文档 已更新为推荐True作为默认值。

1.8 中的默认参数更改可能会为某些用户带来兼容性问题,但我们认为使用安全默认值非常重要。如果不需要对这些函数的调用进行转义,则可以通过传递autoescape=False.

来恢复旧行为。Django 1.0 到 1.7 的用户应检查其代码中对这些过滤器的 Python 调用,并确保任何用法都明确设置autoescape=True

或只传递可信内容。

仅当直接从 Python 代码调用这些模板过滤器(而不是在模板中使用时)时,此问题才会影响它们。

  • 受影响的版本
  • Django 主开发分支(目前处于预发布状态)
  • Django 1.8(目前处于测试版状态)

Django 1.7.6 (下载 Django 1.7.6 | 1.7.6 校验和)

披露安全漏洞

虽然我们总是很高兴收到我们可以修复的错误报告,但我们恳请社区成员不要公开报告安全问题。私下报告允许我们准备可以在公开披露的同时发布的补丁,并预先通知关键组织。另一方面,公开报告会使用户面临更大的风险,并给负责寻找解决方案的团队带来不必要的压力。

有关如何披露漏洞以及 Django 团队如何处理漏洞的信息,请参阅我们的安全发布策略