CSRFjavascript
Cross Site Request Forgery 跨站域请求伪造html
CSRF 攻击能够在受害者绝不知情的状况下以受害者名义伪造请求发送给攻击站点,从而在并未受权的状况下执行在权限保护之下的操做。java
攻击流程:ajax
1,受害者登陆招商银行网站进行了一些正常的操做django
2,受害着在未关闭招商银行网站的状况下,打开了一个被黑客控制的网站浏览器
3,钓鱼网站会引诱受害者触犯转帐请求安全
4,银行处理请求,钱就没有 了服务器
CSRF 攻击的对象cookie
在讨论防护CSRF以前,先要明确CSRF攻击的对象,也就是须要保护的对象。session
CSRF攻击是借助受害者的cookie骗取服务器的信任,可是黑客并不能拿到cookie,也看不到cookie内容。
另外,对于服务器返回的结果,因为浏览器同源策略的限制,黑客也没法进行解析。所以黑客没法从返回的结果中获得任何东西,他所能作到的就是给服务器发送请求,以执行请求中所描述的命令,在服务器端直接改变数据的值,而非窃取服务器中的数据。因此,要保护的对象是那些能够直接产生数据改变的服务,而对于读取数据的服务,则不须要进行CSRF的保护。
防护策略
在请求地址中添加token并验证
CSRF攻击之因此可以成功,是由于黑客能够彻底伪造用户的请求,该请求中全部的用户验证信息都是存在于cookie中,所以黑客能够在不知道验证信息的状况下直接利用用户本身的cookie来经过安全验证。要抵御CSRF关键在于在请求中添加黑客不能伪造的信息,而且该信息不存在cookie中。
能够在http请求中以参数的形式加入一个随机产生的token,并在服务器端创建一个拦截器来验证这个token,若是请求中没有token或者token内容不正确,则认为多是CSRF攻击而拒绝该请求。
token能够在用户登录后产生放在session中,而后在每次请求时把token从session中拿出,与请求中的token进行对比,但这种方法的难点在于如何把token以参数的形式加入请求。
对于GET请求,token将附近在请求地址以后,这样URL就变成了 http://url?csrftoken=tokenvalue
对于POST请求, 要在form的最后加上 <input type="hidden" name="csrftoken" value="tokenvalue" />
这样就包token以参数的形式加入请求了。
可是,在一个网中,能够接受请求的地方很是多,要对于每个请求都加上token是很麻烦的,而且很容易遗漏,一般使用的方式就是在每次页面加载时,使用javascript遍历整个dom树,对于dom中全部a 和 form标签后加入token。
这样就能够解决大部分的请求,可是对于在页面加载以后动态生成的html代码,这种方法就没有做用了,还须要程序在编码时手动添加token。
Django中使用CSRF
使用方法:
1,CSRF的中间件是在 MIDDLEWARE_CLASSES 中默认激活的。‘django.middleware.csrf.CsrfViewMiddleware’,能够禁用,可是这里是不推荐的,可使用 csrf_protect()方法。
2,在form表单后面添加 csrf_token 例如:
<form action="" method="post"> {% csrf_token %}
CSRF AJAX
获取token
1 // using jQuery 2 function getCookie(name) { 3 var cookieValue = null; 4 if (document.cookie && document.cookie != '') { 5 var cookies = document.cookie.split(';'); 6 for (var i = 0; i < cookies.length; i++) { 7 var cookie = jQuery.trim(cookies[i]); 8 // Does this cookie string begin with the name we want? 9 if (cookie.substring(0, name.length + 1) == (name + '=')) { 10 cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); 11 break; 12 } 13 } 14 } 15 return cookieValue; 16 } 17 var csrftoken = getCookie('csrftoken');
上面的代码能够经过使用 javascript 的cookie库中的 getcookie 简化
1 var csrftoken = Cookies.get('csrftoken');
ajax:
function csrfSafeMethod(method) { // these HTTP methods do not require CSRF protection return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); } $.ajaxSetup({ beforeSend: function(xhr, settings) { if (!csrfSafeMethod(settings.type) && !this.crossDomain) { xhr.setRequestHeader("X-CSRFToken", csrftoken); } } });