Skip to main content

Django中的安全性

本文档是Django安全功能的概述。它包括保护Django供电站点的建议。

跨站脚本(XSS)保护

XSS攻击允许用户将客户端脚本插入其他用户的浏览器。这通常通过将恶意脚本存储在数据库中并在其中被检索并显示给其他用户,或者通过使用户点击将导致攻击者的JavaScript由用户的浏览器执行的链接来实现。然而,XSS攻击可以源自任何不受信任的数据源,例如Cookie或Web服务,只要数据在包含在页面中之前未被充分地清理。

使用Django模板保护您免受大多数XSS攻击。然而,重要的是要了解它提供的保护及其限制。

Django模板 转义特定字符 对HTML特别危险。虽然这可以保护用户免受大多数恶意输入,但它并不完全是万无一失的。例如,它不会保护以下内容:

<style class={{ var }}>...</style>

如果 var 设置为 'class1 onmouseover=javascript:func()',这可能导致未经授权的JavaScript执行,这取决于浏览器呈现不完美的HTML的方式。 (引用属性值将修复此情况。)

在使用带有自定义模板标签,safe 模板标签,mark_safeis_safe 以及关闭自动转义时,特别小心也很重要。

此外,如果使用模板系统输出HTML以外的内容,则可能存在需要转义的完全独立的字符和单词。

在数据库中存储HTML时,还应该非常小心,特别是当检索和显示HTML时。

跨站点请求伪造(CSRF)保护

CSRF攻击允许恶意用户在没有该用户的知识或同意的情况下使用另一用户的凭证来执行动作。

Django内置了针对大多数类型的CSRF攻击的保护,只要你有合适的 启用并使用它。然而,与任何缓解技术一样,存在限制。例如,可以全局或针对特定视图禁用CSRF模块。你应该这样做,如果你知道你在做什么。如果您的网站具有不受您控制的子域,则还有其他 限制

CSRF保护工作 通过在每个POST请求中检查一个秘密。这确保恶意用户不能简单地“重放”表单POST到您的网站,并让另一个登录用户不知不觉地提交该表单。恶意用户必须知道秘密,这是用户特定的(使用cookie)。

当与 HTTPS 一起部署时,CsrfViewMiddleware 将检查HTTP引用程序头是否设置为同一来源(包括子域和端口)上的URL。由于HTTPS提供了额外的安全性,因此必须通过转发不安全的连接请求并使用HSTS支持浏览器,确保连接使用HTTPS。

使用 csrf_exempt 装饰器标记视图时要非常小心,除非它是绝对必要的。

SQL注入保护

SQL注入是一种恶意用户能够在数据库上执行任意SQL代码的攻击类型。这可能导致记录被删除或数据泄露。

通过使用Django的查询集,产生的SQL将被底层数据库驱动程序正确转义。然而,Django还给开发人员写入 原始查询 或执行 自定义sql。这些功能应该谨慎使用,你应该始终小心正确地转义用户可以控制的任何参数。此外,使用 extra()RawSQL 时应谨慎。

点击保护

点击劫持是一种攻击,其中恶意网站在框架中包装另一个网站。这种攻击可以导致不知情的用户被欺骗以在目标站点上执行无意的动作。

Django包含以 X-Frame-Options middleware 形式的 点击劫持保护,在支持的浏览器中,它可以防止网站在框架内显示。可以在每个视图的基础上禁用保护或配置发送的精确头值。

强烈建议对于不需要将其页面由第三方网站包装在框架中的任何网站,或者只需要允许该网站的一小部分。

SSL/HTTPS

将安全性部署在HTTPS之后总是更好。否则,恶意网络用户可能嗅探在客户端和服务器之间传输的身份验证凭证或任何其他信息,在某些情况下 - 活性 网络攻击者 - 可能更改在任一方向发送的数据。

如果您想要HTTPS提供的保护并在服务器上启用它,则还需要执行一些其他步骤:

  • 如有必要,设置 SECURE_PROXY_SSL_HEADER,确保您已了解彻底的警告。不这样做可能会导致CSRF漏洞,并且无法正确执行也可能是危险的!

  • SECURE_SSL_REDIRECT 设置为 True,以便通过HTTP的请求将重定向到HTTPS。

    请注意 SECURE_PROXY_SSL_HEADER 下的注意事项。对于反向代理的情况,将主Web服务器配置为执行到HTTPS的重定向可能更容易或更安全。

  • 使用“安全”Cookie。

    如果浏览器最初通过HTTP连接(这是大多数浏览器的默认设置),则可能会泄露现有的Cookie。因此,您应该将 SESSION_COOKIE_SECURECSRF_COOKIE_SECURE 设置设置为 True。这将指示浏览器只通过HTTPS连接发送这些cookie。注意,这将意味着会话将不能通过HTTP工作,并且CSRF保护将阻止通过HTTP接受任何POST数据(如果您将所有HTTP流量重定向到HTTPS,这将是罚款)。

  • 使用 HTTP严格传输安全 (HSTS)

    HSTS是一个HTTP头,通知浏览器所有未来与特定站点的连接应始终使用HTTPS。结合通过HTTP重定向请求到HTTPS,这将确保连接总是享受SSL的增加的安全性,只要一个成功的连接发生了。 HSTS可以使用 SECURE_HSTS_SECONDSSECURE_HSTS_INCLUDE_SUBDOMAINS 或Web服务器进行配置。

主机头验证

Django使用客户端提供的 Host 头在某些情况下构造URL。虽然这些值被清理以防止跨站点脚本攻击,假 Host 值可用于跨站点请求伪造,缓存中毒攻击和电子邮件中的中毒链接。

因为即使看似安全的Web服务器配置也容易伪造 Host 头文件,Django在 django.http.HttpRequest.get_host() 方法中针对 ALLOWED_HOSTS 设置验证 Host 头文件。

此验证仅适用于 get_host();如果您的代码直接从 request.META 访问 Host 头,则您将绕过此安全保护。

有关更多详细信息,请参阅完整的 ALLOWED_HOSTS 文档。

警告

本文档的先前版本建议配置Web服务器以确保其验证传入的HTTP Host 头。虽然这仍然是建议,在许多常见的Web服务器,似乎验证 Host 头的配置可能实际上不这样做。例如,即使Apache配置为使您的Django站点从具有 ServerName 集合的非默认虚拟主机提供,HTTP请求仍然可能匹配此虚拟主机并提供假 Host 标头。因此,Django现在要求您明确设置 ALLOWED_HOSTS,而不是依赖于Web服务器配置。

此外,如果您的配置需要,Django要求您显式启用对 X-Forwarded-Host 头的支持(通过 USE_X_FORWARDED_HOST 设置)。

会话安全

类似于 CSRF限制 要求部署站点,使得不受信任的用户不能访问任何子域,django.contrib.sessions 也具有限制。有关详细信息,请参阅 会话主题指南部分关于安全

用户上传的内容

注解

考虑 从云服务或CDN提供静态文件 以避免其中的一些问题。

  • 如果您的网站接受文件上传,强烈建议您将Web服务器配置中的这些上传限制为合理的大小,以防止拒绝服务(DOS)攻击。在Apache中,这可以使用 LimitRequestBody 指令轻松设置。

  • 如果您正在提供自己的静态文件,请确保像Apache的 mod_php 这样的处理程序(它将以代码执行静态文件)禁用。您不希望用户通过上传和请求特制文件来执行任意代码。

  • 当媒体以不遵循安全最佳实践的方式提供时,Django的媒体上传处理带来一些漏洞。具体来说,如果HTML文件包含有效的PNG标头,然后是恶意HTML,则可以将其上传为图片。该文件将通过对Django用于 ImageField 图像处理(Pillow)的库的验证。当此文件随后显示给用户时,可能会显示为HTML,具体取决于Web服务器的类型和配置。

    在框架级别上没有安全验证所有用户上传的文件内容的防弹技术解决方案,但是,还可以采取一些其他步骤来减轻这些攻击:

    1. 通过始终提供来自不同顶级域或二级域的用户上传的内容,可以防止一类攻击。这可以防止任何利用 same-origin policy 保护(例如跨站点脚本)阻止的漏洞。例如,如果您的网站在 example.com 上运行,则您需要从类似 usercontent-example.com 的内容中提供上传的内容(MEDIA_URL 设置)。 not 足以提供来自 usercontent.example.com 等子域的内容。

    2. 除此之外,应用可以选择为用户上传的文件定义允许的文件扩展名的白名单,并将web服务器配置为仅服务这些文件。

其他安全主题

虽然Django提供了很好的安全保护,但是正确部署应用程序并利用Web服务器,操作系统和其他组件的安全保护仍然很重要。

  • 确保您的Python代码在Web服务器的根之外。这将确保您的Python代码不会意外地作为纯文本(或意外执行)。

  • 照顾任何 用户上传的文件

  • Django不会限制请求以验证用户。为了防止对认证系统的暴力攻击,您可以考虑部署一个Django插件或Web服务器模块来限制这些请求。

  • 保持你的 SECRET_KEY 的秘密。

  • 使用防火墙限制缓存系统和数据库的可访问性是个好主意。

  • 请查看Open Web应用程序安全项目(OWASP) Top 10 list,它确定了Web应用程序中的一些常见漏洞。虽然Django有工具来解决一些问题,但在项目的设计中必须考虑其他问题。