csrf(Cross Site Request Forgery, 跨站域请求伪造:CSRF 攻击容许恶意用户在另外一个用户不知情或者未赞成的状况下,以他的身份执
行操做。javascript
CSRF 攻击是黑客借助受害者的 cookie 骗取服务器的信任,可是黑客并不能拿到 cookie,也看不到 cookie 的内容。另外,对于服务器返回的结果,因为浏览器同源策略的限制,黑客也没法进行解析。所以,黑客没法从返回的结果中获得任何东西,他所能作的就是给服务器发送请求,以执行请求中所描述的命令,在服务器端直接改变数据的值,而非窃取服务器中的数据 。黑客没法获取cookie和session值更没法进行解析。html
假如用户A在某电商网站注册过而且用户本地浏览器又存在网站服务端颁发给本身的通行证(也就是cookie),那么对于用户A来讲本身访问网站而且提交请求购买商品都是畅通无阻,不须要身份验证。可是黑客B想要利用A的帐户给本身买东西,用户B直接访问电商网站固然没法实现这一目的,缘由是B没有A的通行证,想要利用A的帐户在访问网站时又不知道A的密码。那么B本身建造了一个黑客网站,这个黑客网站中存在跳转向目标电商网站的黑客url连接,url连接又包含了用户的请求(假如是A购买了一个iphone X发给某地址,固然这是B想要的地址)。当用户访问黑客网站时,点击黑客连接时,目标网站就会接受到请求,因为该请求是A的浏览器发出的,因此又包含A的cookie,服务端就会将一个iphone X发往B的地址,那么黑客B的目的就达到了。因此在csrf中黑客B并不知道A的cookie,只是间接利用了cookie,拿着A的通行证瞒过目标网站,实现本身目的。java
黑客网页存在指向目标站点的连接,直接跳转程序员
黑客网页存在,其中xxx就是指向目标站点的连接,而且包含请求,例如 src=”http://goumai.example/withdraw?account=A&goods=iphonex&for=B ”ajax
黑客网页包含动态加载的JavaScript,存在转向目标站点的动做。sql
CSRF 攻击之因此可以成功,是由于黑客能够彻底伪造用户的请求,该请求中全部的用户验证信息都是存在于 cookie 中,所以黑客能够在不知道这些验证信息的状况下直接利用用户本身的 cookie 来经过安全验证。要抵御 CSRF,关键在于在请求中放入黑客所不能伪造的信息,而且该信息不存在于 cookie 之中。能够在 HTTP 请求中以参数的形式加入一个随机产生的 token,并在服务器端创建一个拦截器(中间件:django.middleware.csrf.CsrfViewMiddleware)来验证这个 token,若是请求中没有 token 或者 token 内容不正确,则认为多是 CSRF 攻击而拒绝该请求。django
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。dom对象以及cookie浏览器
<form action="/login/" method="POST"> {# {{ csrf_token }}#} {{ csrf_token }}表示随机字符串交给服务端经过测试并隐藏在页面的input中 {% csrf_token %} {# 随机字符串隐藏在页面中的<input>中发送给后台#} <input type="text" name="user"/> <input type="text" name="pwd"/> <input type="submit" value="提交"/> </form>
$(function () { {# 在Ajax请求前设置请求头#} $.ajaxSetup({ beforeSend: function (xhr, settings) { xhr.setRequestHeader('X-CSRFtoken', $.cookie('csrftoken')); } }); $('#btn').click(function () { $.ajax({ {# 关于ajax中data#} {# 第一个data就是发送给服务端的数据,success里面的data是服务器返回的数据#} url: '/login', type:'POST', data:{'user':'root', "pwd":'123'}, headers:{'X-CSRFtoken': $.cookie('csrftoken')}, {# 请求头中不能出现下划线不然视为非法#} success: function (data) { console.log(data); alert(data); }, error: function (data) { alert(data); } } ) }) });
对于Ajax提交时一般还须要对提交请请求的方法进行判断若是是get,head,options,trace方法,不会改变数据,CSRF 攻击
没法解析服务器返回的结果,无需保护。则不须要进行携带csrftoken因此请求前须要进行判断、安全
<script type="text/javascript"> var csrftoken = $.cookie('csrftoken'); 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); } } }); function Do(){ $.ajax({ url:"/app01/test/", data:{id:1}, type:'POST', success:function(data){ console.log(data); } }); } </script>
xss攻击服务器
更多请参考
CSRF攻击与防护