标签:
CSRF
Cross Site Request Forgery 跨站域请求伪造
CSRF 攻击可以在受害者毫不知情的情况下以受害者名义伪造请求发送给攻击站点,从而在并未授权的情况下执行在权限保护之下的操作。
攻击流程:
1,受害者登录招商银行网站进行了一些正常的操作
2,受害着在未关闭招商银行网站的情况下,打开了一个被黑客控制的网站
3,钓鱼网站会引诱受害者触犯转账请求
4,银行处理请求,钱就没有 了
CSRF 攻击的对象
在讨论防御CSRF之前,先要明确CSRF攻击的对象,也就是需要保护的对象。
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); } } });
标签:
原文地址:http://www.cnblogs.com/binges/p/5570659.html