Djang学习17-安全


翻译自Djangov2.1的安全相关: https://docs.djangoproject.com/en/2.1/topics/security/

XSS保护

跨站脚本攻击(Cross-site scripting)是一种安全漏洞,攻击者可以利用这种漏洞在网站上注入恶意的客户端代码。当被攻击者登陆网站时就会自动运行这些恶意代码,从而,攻击者可以突破网站的访问权限,冒充受害者。这种攻击通常是通过将恶意脚本存储在将被检索并显示给其他用户的数据库中来实现,或是让用户点击一些不可靠的链接导致攻击者JavaScript脚本在用户的浏览器上运行了。 但是,只要数据在包含在页面中之前没有充分杀毒,XSS 攻击就可能来自任何不受信任的数据源,例如cookie或Web服务。
使用Django模板可以保护用户免受大多数XSS攻击。 但是,了解它提供的保护措施及其局限性非常重要。Django模板可以转义对HTML来说特别危险的特定字符。 虽然这可以保护用户免受大多数恶意攻击,但它并非完全万无一失。 例如,它不会保护以下内容:

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

如果将var设置为'class1 onmouseover = javascript:func()',则可能导致未经授权的JavaScript执行,具体取决于浏览器呈现不完善的HTML的方式。 (引用属性值可以解决这种情况。)
is_safe与自定义的标签一起使用时,或是使用safe标签、mark_safe标签、自动转义autoescape被关闭时,都要特别注意。
此外,如果使用模板系统输出HTML以外的内容时,可能存在完全独立的字符和单词,它们也需要转义。
在数据库中存储HTML时,也要非常小心,尤其在检索和显示HTML时。

CSRF保护

跨站请求伪造(Cross site request forgery)攻击是攻击者使用了其他用户的身份进行操作,以该用户的名义发送恶意请求,而无需该用户的同意,甚至用户完全不知情。举个例子,很久没有登录的微博,发现自己转发、点赞了一大堆促销、代购之类的广告,很可能就是遭遇了CSRF攻击。
Django内置了针对大多数类型的CSRF攻击的保护,只要在适当的地方使用它们。然而,这也有局限性。例如,可以尝试全局性的或是针对某个特定的视图禁用CSRF模块。如果网站还包含了超出自己控制范围的子域,又会有其他限制。
CSRF 攻击之所以能够成功,是因为黑客可以完全伪造用户的请求,该请求中所有的用户验证信息都是存在于 cookie 中,因此黑客可以在不知道这些验证信息的情况下直接利用用户自己的 cookie 来通过安全验证。要抵御 CSRF,关键在于在请求中放入黑客所不能伪造的信息,并且该信息不存在于 cookie 之中。可以在 HTTP 请求中以参数的形式加入一个随机产生的 token,并在服务器端建立一个拦截器来验证这个 token,如果请求中没有 token 或者 token 内容不正确,则认为可能是 CSRF 攻击而拒绝该请求。
Django的CSRF保护是通过在用户提交的表单中加入一个csrftoken的隐含值(这个值和服务器中保存的csrftoken的值相同)来实现的,原理是:

  1. Django 会通过CsrfViewMiddleware生成一个CSRF cookie,其他的站点无法访问它。出于安全考虑,每次用户登录后,这个值都会改变。
  2. 在所有的 POST 表单时,必须包含一个csrfmiddlewaretoken的隐藏表单字段,每次提交表单时该值都会改变。可以通过标签{% csrf_token %}实现。
  3. 对于未使用HTTP GET,HEAD,OPTIONS或TRACE的所有传入请求,Django 会验证这个请求的 CSRF cookie , 而且的表单里的 csrfmiddlewaretoken 字段的值必须存在且正确。否则,这个请求可能是来自于别人的 csrf 攻击,返回 403 Forbidden。这个检查也是通过CsrfViewMiddleware实现的。
  4. 对于HTTPS请求,Django还会严格地检查Referer首部字段是否设置为同一源(包括子域和端口)上的URL

这可确保只有源自受信任域的表单才能用于POST提交数据。
除了添加django.middleware.csrf.CsrfViewMiddlewareMIDDLEWARE外,还可以手动使用csrf_protect装饰器,保护视图函数:

from django.shortcuts import render
from django.views.decorators.csrf import csrf_protect

@csrf_protect
def my_view(request):
    c = {}
    # ...
    return render(request, "a_template.html", c)

csrf_exempt装饰器会将视图标记为免于中间件的保护,需要谨慎使用。

from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def my_view(request):
    return HttpResponse('Hello world')

SQL注入保护

如果允许通过网页获取用户输入的数据并将其插入一个L数据库,那么就有可能发生SQL注入安全的问题。恶意用户可以在数据库上执行任意SQL代码。 这可能导致记录被删除或数据泄漏。
Django的查询集(querysets)不受SQL注入的影响,因为它们的查询是使用查询参数化构造的。 查询的SQL代码与查询的参数分开定义。 由于参数可能是用户提供的,因此不安全,因此它们会被底层数据库驱动程序转义。
Django还为开发人员提供了编写原生查询或执行自定义sql的能力。 应谨慎使用这些功能,并且应始终小心地正确转义用户可以控制的任何参数。 此外,使用extra()和RawSQL时应谨慎。

Clickjacking保护

点击劫持,也被称为UI-覆盖攻击。它是通过覆盖不可见的框架误导受害者点击。虽然受害者点击的是他所看到的网页,但其实他所点击的是被黑客精心构建的另一个置于原网页上面的透明页面。这种攻击利用了HTML中<iframe>标签的透明属性。
Django的X-Frame-Options中间件提供了点击劫持保护,在支持的浏览器中可以防止站点在frame内呈现。可以基于每个视图禁用保护,或配置发送的确切的首部值。如果站点不需要将它们的网页包含在第三方网站的框架中,或是站点只需要允许第三方网站的一小部分,强烈建议使用这个中间件进行保护。

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 Strict Transport Security(HSTS)
    HSTS是一个HTTP首部,它通知浏览器在未来所有与特定站点的连接必须采用HTTPS来发起连接。结合将请求通过HTTP重定向到HTTPS,这将确保连接始终享有SSL的附加安全性,前提是已成功建立连接。 HSTS使用SECURE_HSTS_SECONDSSECURE_HSTS_INCLUDE_SUBDOMAINSSECURE_HSTS_PRELOAD配置,也可以配置在Web服务器上。

Host header validation

Host 协议头验证。某些情况下,Django使用客户端提供的Host header来构造URL。虽然这些值可以被审查,来防止跨站脚本攻击(XSS),但是一个假的Host值可以用于跨站请求伪造(CSRF),有害的缓存攻击,以及email中的有害链接。
因为即使表面上看起来安全的web服务器也容易被篡改Host headers,Django会验证django.http.HttpRequest.get_host()方法返回的HOST和setting中的ALLOWED_HOSTS的设置允许的HOST。
验证只通过get_host()来实现;如果代码从request.META中直接访问Host协议头,就会绕开这一安全防护。详见完整的ALLOWED_HOSTS文档。

Session security

CSRF限制部署后的站点,不受信任的用户无权访问任何子域。类似的,Django的会话也有相似的限制。详细参照会话部分。

User-uploaded content

用户上传相关的问题。(可以考虑在云服务器或CDN上面部署静态文件来避免这些问题)

  • 如果你的站点接受上传文件,强烈推荐你在web服务器配置中,将这些上传限制为合理的大小,来避免拒绝服务(DOS)攻击。在Apache中,这可以简单地使用LimitRequestBody指令。
  • 如果你自己处理静态文件,确保像Apache的mod_php的处理器已关闭,它会将静态文件当做代码执行。您不希望用户通过上传和请求特制文件来执行任意任意代码。
  • 当媒体以不遵循安全最佳实践的方式提供服务时,Django的媒体上传处理会带来一些漏洞。例如,一个HTML文件可以被当做图片上传,只要文件内包含一个有效的PNG header然后跟着一段恶意的HTML。这个文件会通过Django的图片上传处理程序(Pillow)的验证。当此文件随后显示给用户时,可能会显示为HTML,这具体取决于Web服务器的类型和配置。
    在框架级别上尚无对用户上传内容进行验证的技术解决方案,但可以采取其它一些步骤来抵御这些攻击:
    1. 通过始终从不同的顶级域或二级域提供用户上载的内容,可以防止一类攻击。 这可以防止任何被同源策略保护阻止的漏洞,例如跨站点脚本。 例如,如果您的网站在example.com上运行,您可能希望从usercontent-example.com等服务上传内容(MEDIA_URL设置)。 仅提供来自usercontent.example.com等子域的内容是不够的。
    2. 除此之外,应用程序可以选择为用户上载的文件定义允许的文件扩展名的白名单,并将Web服务器配置为仅提供此类文件。

其它

虽然Django提供了开箱即用的,良好的安全保护,但是合理地部署你的应用,以及利用web服务器、操作系统和其他组件的安全保护仍然很重要。

  • 确保你的Python代码在web服务器的根目录外。这会确保你的Python代码不会意外被解析为纯文本(或者意外被执行)。
  • 小心处理用户上传的文件;
  • Django并不限制验证用户的请求。要保护验证系统免于暴力破解攻击,你可以考虑部署一个Django的插件或者web服务器模块来限制这些请求。
  • SECRET_KEY要保存好;
  • 使用防火墙来限制对缓存系统和数据库的访问;
  • 可以查看Open Web Application Security Project(OWASP)前10名列表,该列表标识了Web应用程序中的一些常见漏洞。 虽然Django拥有解决某些问题的工具,但在项目设计中必须考虑其他问题。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值