📅  最后修改于: 2023-12-03 15:30:28.528000             🧑  作者: Mango
Cross-site request forgery (CSRF)
,中文名为“跨站请求伪造”,简称为 CSRF。它是一种常见的 Web 漏洞,攻击者可以在不知情的情况下,伪造用户已登录的身份,对服务器进行非法操作,比如更改用户密码、发送邮件、转账等。
举个例子,一个名为 A 的用户登录了自己的网上银行,产生了一个登录状态。此时,该用户未退出账户,如果恶意网站 B 同时被访问,该网站 B 含有恶意代码,那么 A 用户在不知情的情况下,会误操作向 A 用户的银行账户发起转账请求并完成操作。
Django 在引入 CSRF(跨站请求伪造) 保护机制之前,对于用户登录信息的验证是基于 sessionid 和 cookies 的。而这种验证方法是存在安全漏洞的,比如中间人攻击、恶意程序等。
为了保证用户的请求是合法的,Django 引入了 CSRF 保护机制,在用户发出 POST、PUT、PATCH、DELETE 等非幂等请求时,Django 会对该请求进行验证,以保证请求来源是合法的。
Django 中的 CSRF 保护机制的基本思路为:向用户返回带有完整性验证信息的 CSRF Token,在和表单一起提交,后台需要对该 Token 进行验证,通过验证才可以接受该表单的提交数据。
Django 的 CSRF Token,是一串随机生成的字符串,可以在表单中嵌入,且是唯一的。
Django 中的 CSRF Token 的生成方式为:
from django.middleware import csrf
token = csrf.get_token(request) # 生成 csrf Token
生成的 Token 默认嵌入到表单中:
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
在表单中添加 CSRF Token 可以防止 CSRF 攻击,也保证了表单提交的安全性。
Django 自带了 CSRF Token 在表单内的实现,只需要在表单中添加 {% csrf_token %}
语句。
from django import forms
class MyForm(forms.Form):
my_field = forms.CharField()
# 模板
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">提交</button>
</form>
如果使用 Ajax 请求,需要在请求头中添加 CSRF Token。
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrf_token);
}
}
});
其中 csrf_token
是 Django 在每个 request 中自动添加的 csrf_token。
X-Content-Type-Options: nosniff
。X-XSS-Protection: 1; mode=block
。Content-Security-Policy
。通过使用 Django 中的 CSRF Token,可以有效地防止 CSRF 攻击,保证表单提交的安全性。同时,除了使用 Django 中的 CSRF Token,还需采取其他安全措施,以防范其他形式的攻击。