csrf 跨站请求伪造
csrf 跨站请求伪造
简介
CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性
可以这样来理解:
攻击者盗用了你的身份,以你的名义发送恶意请求,对服务器来说这个请求是完全合法的,但是却完成了攻击者所期望的一个操作,比如以你的名义发送邮件、发消息,盗取你的账号,添加系统管理员,甚至于购买商品、虚拟货币转账等。 如下:其中Web A为存在CSRF漏洞的网站,Web B为攻击者构建的恶意网站,User C为Web A网站的合法用户
csrf 攻击原理
crsf应用
form表单里应用
<form action="" method="post">
{% csrf_token %}
<p>username:<input type="text" name="username"></p>
<p>target_user:<input type="text" name="target_user"></p>
<p>money:<input type="text" name="money"></p>
<input type="submit">
</form>
在ajax应用
# ajax如何符合校验
// 第一种 利用标签查找获取页面上的随机字符串
{#data:{"username":'jason','csrfmiddlewaretoken':$('[name=csrfmiddlewaretoken]').val()},#}
// 第二种 利用模版语法提供的快捷书写
{#data:{"username":'jason','csrfmiddlewaretoken':'{{ csrf_token }}'},#}
// 第三种 通用方式直接拷贝js代码并应用到自己的html页面上即可
data:{"username":'jason'}
第三种方式的js代码
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('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);
}
}
});
csrf 相关装饰器
全站禁用:注释掉中间件 'django.middleware.csrf.CsrfViewMiddleware',
FBV使用
from django.views.decorators.csrf import csrf_exempt,csrf_protect
# 不再检测,局部禁用(前提是全站使用)
# @csrf_exempt
# 检测,局部使用(前提是全站禁用)
# @csrf_protect
def csrf_token(request):#
if request.method=='POST':
print(request.POST)
return HttpResponse('ok')
return render(request,'csrf_token.html')#
CBV使用
from django.views.decorators.csrf import csrf_protect,csrf_exempt
from django.utils.decorators import method_decorator
# 注释掉csrf
# @method_decorator(csrf_protect,name='post') # 针对csrf_protect第二种 可以需要校验
class MyCsrf(View):
@method_decorator(csrf_protect)# 针对csrf_protect第三种 可以需要校验
def dispatch(self, request, *args, **kwargs):
return super(MyCsrf,self).dispatch(request,*args,**kwargs)
def get(self,request):
return HttpResponse('get')
# @method_decorator(csrf_protect) # 针对csrf_protect第一种 可以需要校验
def post(self,request):
return HttpResponse('post')
# 不注释csrf
#@method_decorator(csrf_exempt,name='post')# 第二种针对csrf_exempt,想忽略全局校验 还是需要校验
class MyCsrf(View):
# @method_decorator(csrf_exempt) # 第三种针对csrf_exempt,想忽略全局校验 可以不需要
def dispatch(self, request, *args, **kwargs):
return super(MyCsrf,self).dispatch(request,*args,**kwargs)
def get(self,request):
return HttpResponse('get')
# @method_decorator(csrf_exempt) # 第一种针对csrf_exempt,想忽略全局校验 还是需要校验
def post(self,request):
return HttpResponse('post')
针对不注释掉csrf的,第三种可以忽略校验,但是一和二不行,还是需要校验