参考链接地址:https://yiyibooks.cn/xx/Django_1.11.6/ref/csrf.html
-
一个基于随机secret值的CSRF cookie,其它站点无法获取到。
此Cookie由
CsrfViewMiddleware
设置。 它和每个响应一起发送,如果请求上没有设置,则调用django.middleware.csrf.get_token()
(这个函数用于内部获取CSRF token)。为了防止BREACH攻击,token不仅仅是secret;一个随机的salt被添加到secret中,并用来加扰它。
出于安全考虑,每当用户登录时,secret的值都会更改。
-
所有传出POST表单中都有一个名为“csrfmiddlewaretoken”的隐藏表单字段。 该字段的值还是这个secret的值,其中添加了salt并且用于加扰它。 在每次调用
get_token()
时重新生成salt,所以在每个响应中这个表单字段值都会改变。此部分由模板标记完成。
-
对于所有未使用HTTP GET,HEAD,OPTIONS或TRACE的传入请求,必须存在CSRF cookie,并且“csrfmiddlewaretoken”字段必须存在且正确。 如果不是,用户将得到403错误。
当验证'csrfmiddlewaretoken'字段值时,只将secret而不是完整的token与cookie值中的secret进行比较。 这允许使用不断变化的token。 虽然每个请求可能使用自己的token,但是secret对所有人来说都是相同的。
此检查由
CsrfViewMiddleware
完成。 -
此外,对于HTTPS请求,
CsrfViewMiddleware
会执行严格的referer检查。 这意味着即使子域可以设置或修改域上的Cookie,也不能强制用户POST给你的应用,因为该请求不是来自精确的域。这也解决了在使用会话独立机密时在HTTPS下可能发生的中间人攻击,由于客户端接受HTTP
Set-Cookie
头(事实上),即使他们正在与HTTPS下的站点通话。 (由于HTTP中存在的Referer
头部不够可靠,因此不会对HTTP请求进行referer检查。)如果设置了
CSRF_COOKIE_DOMAIN
设置,则会将referer与之进行比较。 这个设置支持子域。 例如,CSRF_COOKIE_DOMAIN = '.example.com'
将允许来自www.example.com
和api.example.com
的POST请求。 如果这个设置未设置,则referer必须匹配HTTP的Host
头部。可以使用
CSRF_TRUSTED_ORIGINS
设置扩展接受的引荐者超出当前主机或Cookie域。
这样可以确保只有源自可信域的表单才能用于POST数据。
它故意忽略GET请求(以及由 RFC 7231定义为“安全”的其他请求)。 这些请求不应该有任何潜在的危险副作用,因此具有GET请求的CSRF攻击应该是无害的。 RFC 7231将POST,PUT和DELETE定义为“不安全”,所有其他方法也被认为是不安全的,以实现最大的保护。
CSRF保护不能防止中间人攻击,因此使用HTTP Strict Transport Security使用HTTPS。