Django框架安全
【图书介绍】《Django 5企业级Web应用开发实战(视频教学版)》_django 5企业级web应用开发实战(视频教学版)-CSDN博客
《Django 5企业级Web应用开发实战(视频教学版)》(王金柱)【摘要 书评 试读】- 京东图书 (jd.com)
本节主要介绍Django框架安全方面的内容。安全是Web应用程序开发中最重要的主题之一,对此Django框架提供了多种保护工具和机制。
10.1.1 安全概述
Django框架安全中包括了保护Django驱动的网站的建议,具体内容如下:
1. 跨站点脚本(XSS)保护
XSS攻击使用户可以将客户端脚本注入其他用户的浏览器中。只要在包含数据到页面中之前未对数据进行充分的清理,XSS攻击就可以源自任何不受信任的数据源,例如Cookie或Web服务。
使用Django模板可保护站点免受大多数XSS攻击,但更重要的是要了解其提供的保护及其限制。Django模板会转义特定字符,这对于HTML来说尤其危险。尽管这可以保护用户免受大多数恶意输入的侵害,但这并不是绝对安全的。
2. 跨站点请求伪造(CSRF)保护
CSRF攻击允许恶意用户使用另一用户的凭据执行操作,而无须该用户的授权或同意。Django拥有针对大多数CSRF攻击的内置保护,只需在适当的地方使用该功能即可。
但是,该功能与任何缓解技术一样,都存在局限性。例如,可以全局禁用CSRF模块或针对特定视图禁用CSRF模块,如果站点具有无法控制的子域,则还会有其他限制。
CSRF保护通过检查每个POST请求中的机密来起作用。这样可以确保恶意用户无法简单地将表单POST“重播”到我们的网站,而让另一个登录用户不经意间提交该表单。恶意用户必须知道特定于用户的秘密(如使用Cookie)。
在与HTTPS一起部署时,CsrfViewMiddleware将检查HTTP引用标头是否设置为相同来源(包括子域和端口)上的URL。因为HTTPS提供了额外的安全性,所以必须通过转发不安全的连接请求并对支持的浏览器使用HSTS,来确保使用HTTPS可用的连接。
另外,除非绝对必要,否则请务必谨慎使用csrf_exempt装饰器标记视图。
3. SQL注入保护
SQL注入是一种攻击,恶意用户能够在数据库上执行任意SQL代码。这可能导致记录被删除或数据被泄露。
由于Django框架的查询集是使用查询参数化构造的,因此可以防止SQL注入。查询的SQL代码是与查询的参数分开定义的。由于参数可能是用户提供的,因此是不安全的,底层数据库驱动程序会对其进行转义。
Django框架还允许开发人员编写原始查询SQL或执行自定义SQL。这些功能应谨慎使用,并且应始终小心谨慎地转义用户可以控制的任何参数。此外,在使用extra()和RawSQL时,应谨慎行事。
4. 点击劫持保护
点击劫持是一种攻击,其中恶意站点将另一个站点包装在框架中,可能导致毫无戒心的用户被诱骗在目标站点上执行意外动作。
Django框架包含X-Frame-Options中间件形式的点击劫持保护,在支持的浏览器中,该中间件可以防止网站在框架内呈现。我们可以基于每个视图禁用保护,也可以配置发送的确切报头值。
强烈建议将中间件用于任何不需要将其页面包装在框架中的第三方站点,或者只需要允许站点的一小部分使用中间件的站点。
5. SSL/HTTPS
在HTTPS后面部署站点对于安全性而言总是更好的选择,否则,恶意网络用户可能会嗅探身份验证凭据或客户端与服务器之间传输的任何其他信息,并且在某些情况下(活动的网络攻击者)可能会更改任一方向发送的数据。
6. Host Header验证
在某些情况下,Django框架使用客户端提供的Host Header构造URL。在清除这些值以防止跨站点脚本攻击的同时,可以将伪造的Host值用于跨站点请求伪造,缓存中毒攻击和电子邮件中的中毒链接。
因为即使是安全的Web服务器配置也容易受到伪造的HostHeader的影响,所以Django框架会根据django.http.HttpRequest.get_host()方法中的ALLOWED_HOSTS设置来验证Host头。
此验证仅通过get_host()方法进行,如果代码直接从request.META访问Host Header,则会绕过此安全保护措施。
7. 会话(Session)安全性
类似于CSRF限制(要求部署站点以使不受信任的用户无法访问任何子域),django.contrib.sessions也具有限制。
10.1.2 点击劫持保护
点击劫持中间件和装饰器提供了易于使用的保护,以防止发生点击劫持。当恶意站点诱使用户单击已加载到隐藏框架或iframe中的另一个站点的隐藏元素时,会发生这种类型的攻击。
如何防止点击劫持呢?现代浏览器采用的是X-Frame-Options HTTP Header,该Header指示是否允许在框架或iframe中加载资源。如果响应包含Header值为SAMEORIGIN的Header,则浏览器将仅在请求源自同一站点的情况下才将资源加载到框架中。如果将Header设置为DENY,则无论哪个站点发出请求,浏览器都将阻止加载资源到框架中。
Django框架提供了一些简单的方法来将该Header包含在网站的响应中:
- 一个简单的中间件,可在所有响应中设置Header。
- 一组视图装饰器,可用于覆盖中间件或仅设置某些视图的Header。
- 如果响应中不存在X-Frame-Options HTTP Header,则仅由中间件或视图装饰器来设置。
通过在项目配置文件setting.py中为全部响应设置X-Frame-Options,可以实现防止点击劫持。如果要为站点中的所有响应设置相同的X-Frame-Options值,则将django.middleware.clickjacking. XFrameOptionsMiddleware放入配置的MIDDLEWARE选项中,具体代码如下:
【代码10-1】
MIDDLEWARE = [
...
'django.middleware.clickjacking.XFrameOptionsMiddleware',
...
]
通过startproject命令生成的Django项目,在设置文件中启用此中间件。
10.1.3 CSRF保护
CSRF中间件和模板标签提供了易于使用的跨站点请求伪造保护。当恶意网站包含链接、表单按钮,或某些旨在使用我们的浏览器访问恶意网站的登录用户的凭据在网站上执行某些操作的JavaScript脚本时,就会发生这种类型的攻击。此外,还涵盖了一种相关的攻击类型——登录CSRF,攻击站点在其中诱骗用户的浏览器使用他人的凭据登录到该站点。
要在视图中利用CSRF保护,请执行以下操作:
默认情况下,在MIDDLEWARE设置中激活CSRF中间件。如果要覆盖该设置,则在假定已处理CSRF攻击的任何视图中间件之前,先添加django.middleware.csrf.CsrfViewMiddleware。如果要禁用该设置,则可以在要保护的特定视图上使用csrf_protect()方法。
在使用POST表单的任何模板中,如果表单用于内部URL,则在<form>元素内使用{% csrf_token %}标记,具体代码如下:
【代码10-2】
<form method="post">
{% csrf_token %}
...
</form>
对于以外部URL为目标的POST表单,则不要这样配置,因为会导致CSRF令牌泄漏,从而导致漏洞。
在相应的视图函数中,确保使用RequestContext进行响应,以便{% csrf_token %}可以正常工作。如果正在使用render()函数,则通用视图或contrib应用程序就已经被覆盖了,因为它们都使用RequestContext。
10.1.4 登录加密
Web应用程序安全性的黄金法则是永远不要信任来自不受信任来源的数据。但是,有时通过不受信任的介质传递数据可能会很有用。例如,加密签名的值可以在不检测任何篡改的情况下安全地通过不受信任的通道传递。
Django框架提供了用于签名的低级API和用于设置与读取签名的Cookie的高级API,这是Web应用程序实现签名的方式。
下面是一些很有用的签名:
- 生成“恢复我的账户”URL路由,以发送给丢失密码的用户。
- 确保存储在隐藏表单字段中的数据未被篡改。
- 生成一次性加密URL,以允许临时访问受保护的资源。
保护SECRET_KEY
在通过使用startproject命令创建新的Django项目时,会自动生成settings.py文件,并获得一个随机的SECRET_KEY值。此值是保护签名数据的关键(保持此安全性至关重要),否则攻击者可能会使用它来生成自己的签名值。
10.1.5 登录加密安全中间件
通过django.middleware.security.SecurityMiddleware中间件对请求/响应周期提供了一些安全性增强,每个设置均可独立启用或禁用。具体设置项目如下:
SECURE_BROWSER_XSS_FILTER
SECURE_CONTENT_TYPE_NOSNIFF
SECURE_HSTS_INCLUDE_SUBDOMAINS
SECURE_HSTS_PRELOAD
SECURE_HSTS_SECONDS
SECURE_REDIRECT_EXEMPT
SECURE_SSL_HOST
SECURE_SSL_REDIRECT
例如,如果将SECURE_HSTS_SECONDS设置为非零整数值,则SecurityMiddleware中间件将在所有HTTPS响应上设置此Header。