Django的安保

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

跨站点脚本(XSS)保护

XSS攻击允许用户将客户端脚本注入其他用户的浏览器。这通常是通过将恶意脚本存储在数据库中并将其检索和显示给其他用户来实现的,或者通过让用户单击一个链接来实现的,该链接将导致攻击者的脚本由用户的浏览器执行。但是,只要数据在包含在页面中之前没有经过充分的清理,XSS攻击就可能来自任何不受信任的数据源,例如Cookie或Web服务。

使用django模板可以防止大多数XSS攻击。然而,了解它提供的保护和局限性是很重要的。

Django模板 escape specific characters 这对HTML尤其危险。虽然这可以保护用户不受大多数恶意输入的影响,但并非完全是万无一失的。例如,它不会保护以下内容:

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

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

使用时要特别小心也很重要 is_safe 使用自定义模板标记, safe 模板标签, mark_safe 以及关闭自动转义时。

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

在数据库中存储HTML时,尤其是检索和显示该HTML时,也应该非常小心。

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

CSRF攻击允许恶意用户使用另一个用户的凭据执行操作,而无需该用户的知情或同意。

Django具有针对大多数类型CSRF攻击的内置保护,前提是 enabled and used it 在适当的情况下。然而,与任何缓解技术一样,也存在局限性。例如,可以全局或针对特定视图禁用CSRF模块。只有当你知道自己在做什么的时候,你才应该这样做。还有其他 limitations 如果您的站点有超出您控制范围的子域。

CSRF protection works 通过检查每个POST请求中的秘密。这可以确保恶意用户无法“重播”到您的网站上的表单帖子,并让另一个登录的用户无意中提交了该表单。恶意用户必须知道这个秘密,这是特定于用户的(使用cookie)。

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

请务必小心标记视图 csrf_exempt 除非是绝对必要的。

SQL注入保护

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

Django的查询集受SQL注入保护,因为它们的查询是使用查询参数化构造的。查询的SQL代码与查询的参数分开定义。由于参数可能由用户提供,因此不安全,因此它们由基础数据库驱动程序进行转义。

Django还为开发人员提供了写作能力 raw queries 或执行 custom sql . 这些功能应该被谨慎地使用,并且您应该总是小心地正确地转义用户可以控制的任何参数。此外,使用时应注意 extra()RawSQL .

点击顶升保护

Clickjacking是一种攻击类型,其中恶意站点将另一个站点包装在一个框架中。这种攻击可能导致一个毫无戒心的用户被诱骗到目标站点上执行意外的操作。

Django包含 clickjacking protectionX-Frame-Options middleware 在支持浏览器中,可以防止在框架内呈现网站。可以基于每个视图禁用保护,也可以配置发送的确切头值。

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

SSL/HTTPS

为了安全起见,最好将站点部署在HTTPS之后。没有这一点,恶意网络用户就可能嗅探身份验证凭证或在客户机和服务器之间传输的任何其他信息,在某些情况下-- 积极的 网络攻击者——改变向任意方向发送的数据。

如果您希望使用HTTPS提供的保护,并在您的服务器上启用了它,则可能需要一些其他步骤:

  • 如有必要,设置 SECURE_PROXY_SSL_HEADER ,确保您完全理解那里的警告。不这样做可能会导致CSRF漏洞,而不正确地这样做也可能是危险的!

  • 集合 SECURE_SSL_REDIRECTTrue ,以便通过HTTP的请求重定向到HTTPS。

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

  • 使用“安全”cookies。

    如果浏览器最初通过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 ,以及 SECURE_HSTS_PRELOAD ,或在Web服务器上。

主机头验证

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

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

此验证仅适用于 get_host() ;如果您的代码访问 Host 标题直接来自 request.META 您正在绕过此安全保护。

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

警告

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

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

推荐人政策

浏览器使用 Referer 作为一种向站点发送用户如何到达站点的信息的方法。通过设置 推荐人政策 您可以帮助保护用户的隐私,在哪些情况下限制 Referer 标题已设置。看到了吗 the referrer policy section of the security middleware reference 有关详细信息。

跨境开放政策

跨域开放策略(COOP)头允许浏览器将顶级窗口与其他文档隔离,方法是将它们放在不同的上下文组中,这样它们就不能直接与顶级窗口交互。如果受Coop保护的文档打开跨域弹出窗口,则弹出窗口的 window.opener 属性将是 null 。Coop可防御跨源攻击。看见 the cross-origin opener policy section of the security middleware reference 了解更多细节。

会话安全

类似于 CSRF limitations 要求部署站点,使不受信任的用户无法访问任何子域, django.contrib.sessions 也有局限性。见 the session topic guide section on security 有关详细信息。

用户上载的内容

备注

考虑 serving static files from a cloud service or CDN 为了避免这些问题。

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

  • 如果您正在服务自己的静态文件,请确保像Apache这样的处理程序 mod_php 将静态文件作为代码执行的,被禁用。您不希望用户能够通过上传和请求一个精心设计的文件来执行任意代码。

  • Django的媒体上载处理在以不遵循安全最佳实践的方式提供媒体服务时会造成一些漏洞。具体地说,如果一个HTML文件包含一个有效的PNG头,后跟一个恶意的HTML,那么该文件可以作为图像上传。此文件将通过Django用于的库的验证 ImageField 图像处理(枕头)。当此文件随后显示给用户时,根据Web服务器的类型和配置,它可能显示为HTML。

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

    1. 通过始终为来自不同顶级或二级域的用户上载内容提供服务,可以防止一类攻击。这可以防止被阻止的任何攻击 same-origin policy 保护,如跨站点脚本。例如,如果您的站点运行在 example.com ,您希望提供上载的内容 MEDIA_URL 设置)来自 usercontent-example.com . 它是 not 足以从子域服务内容 usercontent.example.com .

    2. 除此之外,应用程序可以选择为用户上传的文件定义一个允许的文件扩展名列表,并将web服务器配置为仅为此类文件提供服务。

其他安全主题

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

  • 确保您的Python代码位于Web服务器的根目录之外。这将确保您的Python代码不会被意外用作纯文本(或被意外执行)。

  • 注意任何 user uploaded files .

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

  • 保留你的 SECRET_KEY ,以及 SECRET_KEY_FALLBACKS 如果正在使用,则保密。

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

  • 查看开放式Web应用程序安全项目(OWASP) Top 10 list 它可以识别Web应用程序中的一些常见漏洞。虽然Django有解决某些问题的工具,但在项目的设计中必须考虑到其他问题。

  • Mozilla讨论了关于 web security . 他们的页面还包括适用于任何系统的安全原则。