xss攻击:假设咱们网站的评论里面容许用户写js的时候,每一个人就会看到页面会执行这个js代码,有的是alert,不停的跳出弹框。这个还不算严重的,关键是若是js代码运行的结果不显示在页面上,偷偷的 把cookie发到他本身那去,这样攻击者就可使用这个cookie登陆网站。ajax
CSRF:django
1.原理:cookie
发送请求,第一次打开页面是get请求,请求数据,咱们不只把数据发送过去,并且还偷偷的发了一大堆字符串,这个字符串是加密的,只有本身能够反解。xss
下一次咱们提交数据的时候,要带着字符串来,这样才容许提交,否则的话,就报错,不容许提交数据。函数
这个通常体如今哪呢?post
咱们用django,若是咱们日后台发送post的请求,咱们没有把settings那个中间件注释的话,页面就直接出现403错误,好比:网站
我如今把那个代码的注释去掉:ui
咱们打开咱们的login页面,无论写什么点击提交,都会出现403错误:this
这个就是作了一层防御,get提交方式没有什么问题,一旦你以post方式提交,后台会先来去你发过来的请求里面去找一下那个随机字符串,这个是CSRF生成的字符串。加密
那咱们应该怎么解决这个问题呢?人家这里须要一个随机字符串,咱们传一个就能够了。
在django的内部,也支持生成这个随机的字符串:
在form中我加上这个一个变量:csrf_token:
咱们在刷新一下:
就多了一个字符串,这个字符串就是CSRF的token,之后再提交数据的时候就应该带这个字符串。
可是咱们这样在这里放一个字符串是没有用的,因此咱们要用到下面的东西:
咱们在页面上没有看到那个字符串了,可是咱们看一下生成的HTML代码:
咱们生成了一个隐藏的input,咱们在提交数据的时候,后台就可以拿到这个数据了,拿到了就能够经过了。
那若是咱们没有这个CSRFtoken,会出现什么效果呢?
假设咱们先登陆咱们本身的网站,登陆成功以后 ,咱们先放着,咱们打开其余的网站,提交表单登陆,提交到咱们的网站的网址上,若是咱们没有这个token的话就直接提交了,可是若是有的话,其余网站的表单不可能有咱们本身生成的token,就没有办法进行登陆,这样就至关于作了一步防御的工做。
上面是form表单提交数据,咱们使用的是csrf_token,那若是是ajax提交咱们应该怎么作呢?
咱们上面看到了在HTML中生成了一个隐藏的input,里面有一个字符串,其实在咱们的cookie中也生成了一个:
咱们若是ajax请求,咱们只须要拿到这个cookie的值,放到请求头里发过去就好了:
$(function(){ $('#btn').click(function(){ $.ajax({ url : '/login/', type : 'POST', data : {'user':'root','passwd':'123'}, headers : {'X-CSRFtoken' : $.cookie('csrftoken')}, success : function (data) { }, }); }); });
这样就能够提交成功!
固然若是咱们下面有不少ajax操做,咱们能够在ajaxSetup中添加以后,下面的ajax就不须要了:
<!--在这个里面能够对全部的ajax作一个配置--> $.ajaxSetup({ beforeSend : function (xhr,settings) {<!--xhr:XMLHttpRequest 的对象,全部的ajax底层操做都是用这个,--> xhr.setRequestHeader('X-CSRFtoken' , $.cookie('csrftoken')); } })
在django中咱们还支持:
咱们在MIDDLEWARE中把CSRF注释了,每一个form提交的时候都要加上一个token,不加就没法进行验证,做用于所有。这个很明显是不合理的,由于有的时候咱们说那个函数就不须要加CSRFtoken,会有这种需求。
咱们如今有一个需求,100form提交中有2个须要用到CSRFtoken验证,那怎么作呢?
局部:
注:from django.views.decorators.csrf import csrf_exempt,csrf_protect
CSRF只有在post提交的时候才起做用,若是用get请求,那不须要csrftoken,那咱们能够在上面的ajaxsetup中作判断
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); } } });