阅读(4600) (0)

Django 的安全性

2020-06-13 14:39:09 更新

跨站点脚本(XSS)保护

XSS攻击使用户可以将客户端脚本注入其他用户的浏览器中。通常,这是通过将恶意脚本存储在数据库中进行检索并将其显示给其他用户,或者通过使用户单击链接而导致攻击者的JavaScript由用户的浏览器执行来实现的。但是,只要未在包含在页面中之前对数据进行足够的清理,XSS攻击就可能源自任何不受信任的数据源,例如cookie或Web服务。

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

Django模板会转义特定字符 ,这对于HTML来说尤其危险。尽管这可以保护用户免受大多数恶意输入的侵害,但这并不是绝对安全的。例如,它将不会保护以下内容:

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

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

is_safe与自定义模板标签,safe模板标签一起使用mark_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注入。查询的SQL代码是与查询的参数分开定义的。由于参数可能是用户提供的,因此是不安全的,因此底层数据库驱动程序会对其进行转义。

Django还使开发人员可以编写原始查询或执行自定义sql。这些功能应谨慎使用,并且您应始终小心谨慎地转义用户可以控制的任何参数。此外,使用extra() 和时应格外小心RawSQL。

点击劫持保护

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

Django包含clickjacking保护,其形式为 在支持的浏览器中可以防止网站在框架内呈现。可以基于每个视图禁用保护或配置发送的确切报头值。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_SECURE和 CSRF_COOKIE_SECURE设置设置为True。这指示浏览器仅通过HTTPS连接发送这些cookie。请注意,这将意味着会话将无法通过HTTP进行工作,并且CSRF保护将阻止通过HTTP接受任何POST数据(如果您将所有HTTP流量都重定向到HTTPS,这将很好)。
  • 使用HTTP严格传输安全性(HSTS)HSTS是一个HTTP标头,它通知浏览器将来与特定站点的所有连接都应始终使用HTTPS。结合通过HTTP将请求重定向到HTTPS,这将确保只要发生一次成功的连接,连接就始终可以享受SSL的额外安全性。HSTS既可以与配置SECURE_HSTS_SECONDS, SECURE_HSTS_INCLUDE_SUBDOMAINS以及SECURE_HSTS_PRELOAD,或在Web服务器上。

主机头验证

Host在某些情况下,Django使用客户端提供的标头构造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配置为从具有该ServerName设置的非默认虚拟主机为Django站点提供服务,HTTP请求仍然有可能匹配该虚拟主机并提供​​伪造的Host标头。因此,Django现在要求您进行ALLOWED_HOSTS显式设置,而不是依赖于Web服务器配置。

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

推荐人政策

浏览器使用Referer标头作为向用户发送有关用户到达那里的信息的方式。通过设置引荐来源网址策略,您可以帮助保护用户的隐私,并限制在哪种情况下设置 Referer标头。有关详细信息,请参见安全中间件参考的引荐来源网址策略部分。

会话安全

与CSRF的限制类似,它要求部署网站以使不受信任的用户无法访问任何子域,这 django.contrib.sessions也有限制。有关详细信息,请参见有关安全性的会话主题指南部分

用户上传的内容

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

  • 如果您的站点接受文件上传,则强烈建议您将Web服务器配置中的这些上传限制为合理的大小,以防止拒绝服务(DOS)攻击。在Apache中,可以使用LimitRequestBody指令轻松设置此值。
  • 如果您要提供自己的静态文件,请确保mod_php禁用诸如Apache的处理程序,该处理程序 将静态文件作为代码执行。您不希望用户能够通过上载和请求特制文件来执行任意代码。
  • 当以不遵循安全最佳实践的方式提供媒体时,Django的媒体上传处理会带来一些漏洞。具体来说,如果HTML文件包含有效的PNG标头和恶意HTML,则该HTML文件可以作为图像上传。该文件将通过Django用于ImageField图像处理的库的验证(枕头)。随后将该文件显示给用户时,根据您的Web服务器的类型和配置,它可能会显示为HTML。在框架级别没有可以安全验证所有用户上传文件内容的防弹技术解决方案,但是,您可以采取一些其他步骤来减轻这些攻击:通过始终为来自不同的顶级域或第二级域的用户上传的内容提供服务,可以防止一类攻击。这样可以防止任何由同源策略保护(例如跨站点脚本)阻止的漏洞利用。例如,如果您的网站在上运行example.com,您可能希望通过来提供上载的内容(MEDIA_URL设置)usercontent-example.com。这是不是足以从像一个子域提供内容usercontent.example.com。除此之外,应用程序可能会选择为用户上传的文件定义允许的文件扩展名白名单,并将Web服务器配置为仅提供此类文件。

其他安全主题

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

  • 确保您的Python代码在Web服务器根目录之外。这将确保您的Python代码不会意外地用作纯文本(或意外地执行)。
  • 注意任何用户上传的文件。
  • Django不会限制对用户进行身份验证的请求。为了防止对身份验证系统的暴力攻击,您可以考虑部署Django插件或Web服务器模块来限制这些请求。
  • 保守SECRET_KEY秘密
  • 最好使用防火墙限制缓存系统和数据库的可访问性。
  • 查看开放式Web应用程序安全项目(OWASP)的前10个列表,该列表确定了Web应用程序中的一些常见漏洞。尽管Django拥有解决某些问题的工具,但在项目设计中必须考虑其他问题。
  • Mozilla讨论了有关Web安全的各种主题。他们的页面还包含适用于任何系统的安全性原则。

详情参考: https://docs.djangoproject.com/en/3.0/