首页 > 其他分享 >Djiango:csrf跨站请求伪造

Djiango:csrf跨站请求伪造

时间:2022-12-26 00:00:13浏览次数:61  
标签:跨站 name request 校验 添加 csrf post Djiango

目录

一、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只有第三种方法生效,其他的不方法不支持

标签:跨站,name,request,校验,添加,csrf,post,Djiango
From: https://www.cnblogs.com/DuoDuosg/p/17004870.html

相关文章