Djiango:csrf跨站请求伪造

一、csrf跨站请求伪造

1.csrf简介

CSRF跨站点请求伪造Cross Site Request Forgery,是一种挟持用户在当前已登录的web应用程序上执意非本意的操作的攻击方法。

攻击者盗用了你的身份,以你的名义发送恶意请求,对服务器来说这个请求是完全合法的,但是却完成了攻击者所期望的一个操作,比如以你的名义发送邮件、发消息,盗取你的账号,添加系统管理员,甚至于购买商品、虚拟货币转账等。

2.模拟钓鱼网站案例

某个钓鱼网站,从网址到页面都和真银行网站一摸一样,当你想要通过银行操作业务的时候,他会将你的银行卡号和密码发送给真的银行,但是转账人取被改成洗钱的账户(隐藏的input框)提交给银行,然后通过真银行将钱转走。

image-20201026083553056

  • 后端
def transfer_func(request):
if request.method == "POST":
username = request.POST.get('username')
transfer_name = request.POST.get('transfer_name')
money = request.POST.get('money')
print(f"{username}{transfer_name}转账了{money}元")
return render(request, 'transferPage.html')
  • 钓鱼网站前端

    通过内部隐藏标签,将用户想要转账的转账人更改

image-20221225193129570

二、csrf相关校验策略

在settings中解开注释,开启csrf验证机制,当我们提交POST请求时,在提交数据的位置添加唯一标识,以供后续校验使用

image-20221225193518673

1.form的csrf策略

在form表单内部添加模版语法

{% csrf_token %}

image-20221225193651762

在web浏览器的页面上则会多一个input标签出来,属性name="csrfmiddlewaretoken"value为随机字符串

image-20221225212016300

2.ajax请求csrf策略

(1)方式1:自己手动取值,较为繁琐

在data中添加一个键值对为'csrfmiddlewaretoken':$('input[name="csrfmiddlewaretoken"]').val()

$('.c1').click(function (){
$.ajax({
url:'',
type:'post',
data:{
'csrfmiddlewaretoken':$('input[name="csrfmiddlewaretoken"]').val(),
'username':'duoduo',
'transfer_name':'qiuqiu',
'money':11111,
},
success:function (args){
}
})
})

image-20221225213258437

(2)方式2:利用模版语法自动获取(一定要用引号引起来)

在data中添加一个'csrfmiddlewaretoken':'{{ csrf_token },自动传一个token

$('.c1').click(function (){
$.ajax({
url:'',
type:'post',
data:{
'csrfmiddlewaretoken':'{{ csrf_token }}',
'username':'duoduo',
'transfer_name':'qiuqiu',
'money':11111,
},
success:function (args){
}
})
})

image-20221225212650683

(3)方式3:直接引入一个js脚步(官网提供的)

通过静态文件,为所有ajax发送请求时自动添加上csrftoken及其随机字符串。

static中新建一个js文件,将脚本拷贝进去,并在网页上连接进去

参考:https://www.cnblogs.com/Dominic-Ji/p/9234099.html

  • csrf.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项目都校验csrf,但是某些视图函数/类不校验csrf。

解决:使用csrf提供的装饰器

1.FBV添加csrf校验装饰器

在视图中,为某个函数单独设置需要csrf校验,或者取消单独某个函数的csrf校验。

需要导入以下两个模块。

from django.views.decorators.csrf import csrf_protect # 单独校验
from django.views.decorators.csrf import csrf_exempt # 取消校验
  • @csrf_exempt

    当添加exempt装饰器时,就算在settings中还保存着csrf校验,该函数对应的路由地址也不会开启csrf校验

@csrf_exempt
def transfer_func(request):pass
  • @csrf_protect

    添加protect装饰器,则会开启csrf校验

@csrf_protect
def transfer_func(request):pass

2.CBV添加csrf校验装饰器

当我们和FBV一样添加相同的装饰器给类中的函数的时候,并不会直接报错csrf验证,而是没有cookies。

image-20221225233900688

所以,不能直接给在CBV中的方法添加装饰器,需要导入一个模块,通过该模块的装饰器,给CBV中的方法添加csrf校验功能

# 使用CBV的模块,CBV需要继承该类
from django.views import View
# 添加csrf装饰器的模块
from django.utils.decorators import method_decorator

image-20221225234212099

(1)方式1:单独生效,针对某个方法添加csrf装饰器

class ...():
@method_decorator(csrf_protect)
def post():

(2)方式2:单独生效

给类中的某一个方法添加装饰器

@method_decorator(csrf_protect, name='post')
class MyView(View):
def post(self, request):
return HttpResponse('这里是 MyView 的post')

image-20221225234642668

(3)方式3:给整个类中生效

重写dispatch方法,dispatch是整个CBV方法分发的入口

class MyView(View):
@method_decorator(csrf_protect) # 方式3:重写dispatch方法,为整个类中的方法添加csrf校验
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request, *args, **kwargs)
def post(self, request):
return HttpResponse('这里是 MyView 的post')

image-20221225235110096

特例:csrf_exempt只有第三种方法生效,其他的不方法不支持

posted @   Duosg  阅读(54)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示