摘要
- 网上有很多关于csrf的介绍文章(互抄),致使其解释要么冗余,要么晦涩,要么错误百出,所以本文重在通俗解释,核心解释。
- 有部分内容参考他人博客,侵删。
- CSRF:跨站请求伪造
- post,get及各种请求都有可能存在csrf攻击隐患。
CSRF攻击原理及过程:
1、用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;
2、在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;
3、用户未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B;
4、网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A;
5、浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。
6、网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行。
CSRF攻击的处理(验证过程):
- 要求cookie和请求体或者请求头中都有csrf_token的值
- 关于这个值:
- 值也许是“真正”随机的,
- 也许是利用算法进行混淆处理(类似加密解密的过程),
- 可以肯定的是,作为开发者一定会让这个值每次都不一样。
- 恶意网站是可以设置请求体中csrf_token字段,但是是不可能知道cookie中csrf_token的值的。
- 这是因为,js的同源策略:不同源的网站不能相互操作资源,脚本(js)只能读取和其所属文档来源相同的窗口和属性。
- 假设一个黑客要伪造请求来使银行网站转账:
- 黑客需要提取cookie中的csrf_token是银行资源;
- 黑客在用户访问中设置的请求体是恶意网站的资源。
- 所以不能相互操作。
- 这是因为,js的同源策略:不同源的网站不能相互操作资源,脚本(js)只能读取和其所属文档来源相同的窗口和属性。
补充
- CSRF防护方法有很多种,我就不一一举例,具体可以百度一下,但都逃不过一个思想:造出一个恶意网站造不出来的值
- django是如何实现csrf机制的(中间件之:
process_view
):django是如何实现csrf验证 - flask也是通过钩子函数(类似django的中间件):
@app.before_request
来实现csrf机制的,flask是如何实现csrf验证的。 - django和flask框架的csrf__token的值是依据session机制更新的(当然,这一点可以通过定制的方式来修改它)
另外
django如果通过ajax发送请求时,处理csrf时有两种方式:
- 第一种:在html文件中中随随便找一个合适的位置,写入
{% csrf_token %}
这段代码,然后就可以通过csrf = $('input[name="csrfmiddlewaretoken"]').val()
将其取出,并以参数的形式(这里不是ajax的参数,是ajax中要发送的请求中所携带的参数)放在请求体中。 - 第二种:通过ajax的参数选项直接设置在请求头中:
beforeSend:function(xhr, settings){
xhr.setRequestHeader("X-CSRFToken", "{{ csrf_token }}");
},
如果在flask中,当你配置了csrf验证机制的话,你需要手动的将csrf_token设置在cookie中,然后就可以通过js手段将cookie中对应的csrf__token读取出来,进而通过ajax的参数放入请求头中,达到验证效果。
function getCookie(name) {
var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
return r ? r[1] : undefined;
}
headers:{
"X-CSRFToken":getCookie("csrf_token")
},