目录
csrf跨站请求伪造
1.csrf介绍
CSRF (Cross-site request forgery,跨站请求伪造)也被称为One Click Attack或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装成受信任用户请求受信任的网站。
2.原理
1. 用户打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;
2. 用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;
3. 用户未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B;
4. 网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A;
5. 浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行。
钓鱼网站
模仿正规网站,让用户在这网站上做操作,但是操作的结果会影响到用户正常的官方网站账号.其中就是有些投机分子做了手脚
eg: 四六级考试之前需要网上先缴费,你缴完费发现卡里的钱扣了,但是却交大了一个莫名其妙的账户,并不是教育院考试院
模拟钓鱼网站案例:转账
内部隐藏标签
简易真实网站
<h1>我是真的网站</h1> http://127.0.0.1:8000/transfer/
<form action="" method="post">
<p>付款人:
<input type="text" name="username" >
</p>
<p>收款账户:
<input type="text" name="target_name">
</p>
<p>转账金额:
<input type="text" name="money">
</p>
<input type="submit">
</form>
简易假骗网站
<h1>我是假的网站</h1>
<form action="http://127.0.0.1:8000/transfer/" method="post"> # 是朝真实的网址发送请求的
<p>付款人:
<input type="text" name="username" >
</p>
<p>收款账户:
<input type="text"> # 因为没有name值,是不会发送的
<input type="text" name="target_name" value="黑客jason" style="display: none">
# 利用隐藏的标签,发送真实数据
</p>
<p>转账金额:
<input type="text" name="money">
</p>
<input type="submit">
</form>
如何能区分真假网站页面发送的请求呢?
我们引入了csrf校验策略。我们在访问官方网站时,我们需要访问一些核心页面的时候,我们会给核心页面做唯一的标识,当核心页面朝官方网站发送的请求时,官方会根据唯一标识做判断的,没有标识则有可能是恶意网站
csrf相关校验策略
csrf校验策略可以在提交数据的位置添加唯一标识。
方式一:
1.form表单csrf策略
form表单内部添加{% csrf_token %}
eg:
<h1>我是真的网站</h1>
<form action="" method="post">
{% csrf_token %}
<p>付款人:
<input type="text" name="username" >
</p>
<p>收款账户:
<input type="text" name="target_name">
</p>
<p>转账金额:
<input type="text" name="money">
</p>
<input type="submit">
</form>
2.ajax请求csrf策略
方式一:
<script>
$('#d1').click(function (){
$.ajax({
url:'',
type:'post',
// 方式1:自己动手取值,较为繁琐
data:{'csrfmiddlewaretoken':$('input[name="csrfmiddlewaretoken"]').val()},
success:function (args){
}
})
})
</script>
方式二:
<script>
$('#d1').click(function (){
$.ajax({
url:'',
type:'post',
// 方式2:利用模板语法自动获取(一定要用引号引起来)
data:{'csrfmiddlewaretoken':'{{ csrf_token }}','username':'kimi'},
{#data:{'csrfmiddlewaretoken':$('input[name="csrfmiddlewaretoken"]').val()},#}
success:function (args){
}
})
})
</script>
方式三
// 方式3:直接引入一个js脚本即可(官网提供的)
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);
}
}
});
将上述的文件配置到项目的静态文件中,在html页面上通过导入该文件即可自动帮我们解决ajax提交post数据时校验csrf_token的问题,导入配置文件必须先导入jQuery,因为上述文件的内容时基于jQuery来实现的
csrf相关装饰器
csrf是一个唯一标识,只有在进行第二次请求的时候才会去校验(如get请求就不会校验),校验的位置在setting里面,就是post请求注释掉的哪个位置:
'django.middleware.csrf.CsrfViewMiddleware'
当我们有不一样的要求时:
整个django项目都校验csrf 但是某些个视图函数\类不想校验
整个django项目都不校验csrf 但是某些个视图函数\类需要校验
FBV添加装饰器的方式
与正常函数添加装饰器一致
from django.views.decorators.csrf import csrf_exempt,csrf_protect
# @csrf_exempt # 全局csrf校验时,该装饰器作用是不校验此函数
@csrf_protect # 注释掉csrf,该装饰器还是会校验此函数
def transfer_func(request):pass
CBV添加装饰器的多种方式
与正常情况不一致,需要引入method_decorator模块
# 引入模块
from django import views
from django.utils.decorators import method_decorator
# @method_decorator(csrf_protect, name='post') # 方式2:单独生效
class MyView(views.View):
@method_decorator(csrf_protect) # 方式3:整个类中生效
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request, *args, **kwargs)
# @method_decorator(csrf_protect) # 方式1:单独生效
def post(self, request):
return HttpResponse('from cbv post view')
注意:有一个装饰器是特例,只能由一种添加方法>>>:csrf_exempt,只有在dispatch方法添加才会生效
from django.views.decorators.csrf import csrf_exempt
class MyView(views.View):
@method_decorator(csrf_exempt) # csrf_exempt只能通过第三种方式全类取消csrf校验
def dispatch(request):
return super().dispatch(request, *args, **kwargs)
def get(request):pass
def post(request):pass
标签:跨站,请求,网站,request,校验,csrf,伪造,name
From: https://www.cnblogs.com/zhanglanhua/p/17011045.html