首页 > 其他分享 >【24.0】Django框架之csrf跨站请求

【24.0】Django框架之csrf跨站请求

时间:2024-04-07 18:35:30浏览次数:31  
标签:protect 跨站 csrf 24.0 校验 Django CSRF exempt 请求

【一】跨站请求伪造介绍

【1】引入

  • CSRF(Cross-Site Request Forgery)跨站请求伪造是一种常见的网络攻击方式。
  • 攻击者通过诱导受害者访问恶意网站或点击恶意链接
    • 将恶意请求发送到目标网站上
    • 利用受害者在目标网站中已登录的身份来执行某些操作
    • 从而达到攻击的目的。

【2】举例

  • 假设受害者在一家网银网站上登录账户,然后继续浏览其他网页。
  • 同时,攻击者通过电子邮件等方式向受害者发送了一封包含恶意链接的邮件。
  • 当受害者点击该链接时,潜在的威胁就会变得非常现实。
  • 该链接指向一个由攻击者操纵的网站,该网站上的恶意代码会自动向网银网站发送一个请求,请求转账到攻击者的账户。
  • 由于受害者在网银网站中已经登录,所以该请求会被认为是合法的,这样攻击者就可以成功地进行转账操作。

【3】保护措施

  • 要保护自己免受CSRF攻击,网站开发者可以采取以下措施:

(1)使用CSRF令牌

  • 在用户的请求中添加随机生成的令牌,并将该令牌保存在用户会话中。
  • 每次提交请求时都会验证该令牌,以确保请求是合法的。

(2)启用SameSite属性:

  • 将Cookie的SameSite属性设置为Strict或Lax,以限制跨站请求。
  • 这可以在一定程度上缓解CSRF攻击。

(3)严格验证请求来源

  • 服务器端可以验证请求的来源是否为预期的网站域名
  • 例如检查HTTP Referer头部。

(4)使用验证码

  • 在敏感操作(如转账、更改密码等)上使用验证码
  • 增加用户身份验证的防护。

【二】跨域请求伪造实际案例

【1】钓鱼网站

  • 搭建一个类似正规网站的页面
  • 用户点击网站链接,给某个用户打钱
  • 打钱的操作确确实实提交给了中国银行的系统,用户的钱也确实减少
  • 但是唯一不同的是,账户打钱的账户不是用户想要打钱的目标账户,变成了其他用户

【2】内部本质

  • 在钓鱼网站的页面针对对方账户,只给用户提供一个没有name属性的普通input框
  • 然后在内部隐藏一个已经写好带有name属性的input框

【3】如何避免

  • csrf跨域请求伪造校验
    • 网站在给用户返回一个具有提交数据功能的页面的时候会给这个页面加一个唯一标识
    • 当这个页面后端发送post请求的时候,我们后端会先校验唯一标识
      • 如果成功则正常执行
      • 如果唯一标识不符合则拒绝连接(403 forbidden)

【三】CSRF校验

【1】介绍

  • csrf校验是一种用于防止跨站请求伪造(Cross-Site Request Forgery)攻击的安全措施。

【2】CSRF校验策略

(1)添加CSRF Token字段

  • 在form表单中添加一个隐藏字段,用于存储CSRF Token的值。
  • 后端服务器在渲染表单时生成一个CSRF Token,并将其存储在会话中或者以其他方式关联到当前用户。
  • 当用户提交表单时,前端将CSRF Token的值包含在请求中。
  • 后端在验证表单数据时,检查请求中的CSRF Token是否与存储的Token匹配,如果不匹配,则拒绝请求。

(2)设置Cookie

  • 后端服务器在渲染表单时,在客户端设置一个包含随机生成的CSRF Token的Cookie。
  • 当用户提交表单时,表单数据会被一同发送到服务器,并自动包含该Cookie。
  • 后端在验证表单数据时,检查请求中的CSRF Token是否与Cookie中的值匹配,如果不匹配,则拒绝请求。

(3)双重Cookie校验

  • 后端服务器在渲染表单时,在Cookie中设置一个随机生成的CSRF Token,并将其存储在会话中或以其他方式关联到当前用户。
  • 当用户提交表单时,表单数据会被一同发送到服务器,请求头或请求参数中携带一个包含CSRF Token的自定义字段。
  • 后端在验证表单数据时,同时检查请求中的CSRF Token和Cookie中的值是否匹配,如果不匹配,则拒绝请求。

【四】POST请求校验CSRF

【1】form表单校验CSRF

  • 在form表单上面加上csrf_token
{% csrf_token %}
<form action="" method="post">
    <p>username:<input type="text" name="username"></p>
    <p>transfer_user<input type="password" name="password"></p>
    <p>money<input type="text" name="money"></p>
    <input type="submit">
</form>
  • 在页面标签中会自动出现一个标签
<input type="hidden" name="csrfmiddlewaretoken" value="zQaNPZsy1tVmLdqC7GIDOOOfR7yT9YfO58lJ5yrjZfTw2edZTrVYUllOVMnkwXKe">

【2】Ajax携带CSRF

(1)方式一:获取标签值

  • 利用标签查找获取页面上的随机字符串
  • 键必须叫 csrfmiddlewaretoken
<button id="b1">ajax请求提交</button>

<script>
    $("#b1").click(function () {
        $.ajax({
            url: '',
            type: 'post',
            // (1) 利用标签查找获取页面上的随机字符串
            data: {
              "username": "dream",
              "csrfmiddlewaretoken":$("input[name='csrfmiddlewaretoken']").val()
            },
            success: function () {

            }
        })
    })
</script>

(2)方式二:模板语法取值

  • 利用模板语法进行快捷引入
<button id="b1">ajax请求提交</button>

<script>
    $("#b1").click(function () {
        $.ajax({
            url: '',
            type: 'post',
            // (2) 利用模板语法提供的快捷书写
            data: {
              "username": "dream", 
              "csrfmiddlewaretoken": "{{ csrf_token }}"
            },
            success: function () {

            }
        })
    })
</script>

(3)方式三:js文件配置

  • 定义一个js文件并引入
  • 导入该配置文件之前,需要先导入jQuery,因为这个配置文件内的内容是基于jQuery来实现的
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);
    }
  }
});

<button id="b1">ajax请求提交</button>

<script src="{% static 'js/csrf_check.js' %}"></script>
<script>
    $("#b1").click(function () {
        $.ajax({
            url: '',
            type: 'post',
            // (3) 定义外部js文件并引入到本地
            data: {
              "username": "dream"
            },
            success: function () {

            }
        })
    })
</script>

【五】CSRF相关装饰器

  • 策略一:网站整体部分校验csrf,部分不校验csrf
  • 策略二:网站整体全部校验csrf,部分不校验csrf

【1】csrf_protect装饰器:

  • csrf_protect装饰器用于需要进行CSRF保护的视图函数或类视图。
  • 当一个视图被csrf_protect装饰器修饰时,Django会对该视图接收到的所有POST、PUT、DELETE等非安全HTTP方法的请求进行CSRF校验。
  • 如果请求中没有有效的CSRF令牌或令牌校验失败,Django将返回403 Forbidden响应。

【2】csrf_exempt装饰器:

  • csrf_exempt装饰器用于不需要进行CSRF保护的视图函数或类视图。
  • 当一个视图被csrf_exempt装饰器修饰时,Django将不会对该视图接收到的任何请求进行CSRF校验。
  • 这个装饰器主要用于一些特殊情况,比如与第三方系统进行集成、开放API接口等。

【3】装饰器位置

from django.views.decorators.csrf import csrf_protect, csrf_exempt

【六】FBV中使用CSRF装饰器

from django.views.decorators.csrf import csrf_protect, csrf_exempt
'''
csrf_protect  需要校验
csrf_exempt   忽视校验
'''
# @csrf_protect / @csrf_exempt
def register(request):
  ...
  • 当我们没有注释掉csrf校验中间件的时候,可以在函数头上加上 @csrf_exempt 忽视校验

  • 当我们注释掉csrf校验中间件的时候,可以在函数头上加上 @csrf_protect 强制启动校验

【七】CBV中使用CSRF装饰器

from django.views.decorators.csrf import csrf_protect, csrf_exempt
'''
csrf_protect  需要校验
	针对 csrf_protect 符合之前的装饰器的三种用法
csrf_exempt   忽视校验
	针对 csrf_exempt 只能给 dispatch 方法加才有效
'''

(1)csrf_protect

(1)方式一

  • 给指定方法加@method_decorator
from django.views import View
from django.views.decorators.csrf import csrf_protect, csrf_exempt
from django.utils.decorators import method_decorator


class MyCsrf(View):
    def get(self, request):
        return HttpResponse("get")
    
    @method_decorator(csrf_protect)
    def post(self, request):
        return HttpResponse("post")

(2)方式二

  • 给类加然后指明方法 @method_decorator
from django.views import View
from django.views.decorators.csrf import csrf_protect, csrf_exempt
from django.utils.decorators import method_decorator


@method_decorator(csrf_protect)
class MyCsrf(View):
    def get(self, request):
        return HttpResponse("get")
    
    def post(self, request):
        return HttpResponse("post")

(3)方式三

  • 重写 dispatch 方法
from django.views import View
from django.views.decorators.csrf import csrf_protect, csrf_exempt
from django.utils.decorators import method_decorator


class MyCsrf(View):
    @method_decorator(csrf_protect)
    def dispatch(self, request, *args, **kwargs):
        return super(MyCsrf, self).dispatch(request, *args, **kwargs)

    def get(self, request):
        return HttpResponse("get")

    
    def post(self, request):
        return HttpResponse("post")

【2】csrf_exempt方法

  • 只有重写 dispatch方法 有效
from django.views import View
from django.views.decorators.csrf import csrf_protect, csrf_exempt
from django.utils.decorators import method_decorator


class MyCsrf(View):
    @method_decorator(csrf_exempt)
    def dispatch(self, request, *args, **kwargs):
        return super(MyCsrf, self).dispatch(request, *args, **kwargs)

    def get(self, request):
        return HttpResponse("get")

    
    def post(self, request):
        return HttpResponse("post")

标签:protect,跨站,csrf,24.0,校验,Django,CSRF,exempt,请求
From: https://www.cnblogs.com/dream-ze/p/18119655

相关文章

  • 【23.0】Django框架之中间件引入
    【一】Django中间件介绍【1】什么是Django中间件Django中间件是一个轻量级、可重用的组件,用于处理Django请求和响应的过程。它提供了对请求和响应进行全局处理的机制,可以在请求达到视图之前进行预处理或在响应返回给客户端之前进行后处理。中间件是按照顺序依次执行的,每......
  • 【26.1】Django框架之settings配置
    【一】引言Django项目的设置文件位于项目同名目录下,名叫settings.py。这个模块,集合了整个项目方方面面的设置属性,是项目启动和提供服务的根本保证。【二】简述settings.py文件本质上是一个Python模块,带有模块级别的变量。下面是一些示例设置:ALLOWED_HOSTS=['www.examp......
  • 【26.0】Django框架之settings源码
    【一】Django配置文件介绍Django框架默认提供给我们一个配置文件在我们项目根目录下的setting.py文件中,在里面我们可以看到很多的配置项并且我们能够自主的添加相应的配置但是其实这个文件只是Django暴露出来给我们的一个接口文件,在Django内部还存在一个更加强大的配置文件......
  • 【25.0】Django框架之auth模块
    【一】Auth模块引入我们在创建一个Django项目之后,直接执行数据库迁移命令会自动生成很多表django_sessionauth_userDjango在启动之后就可以直接访问admin路由,需要输入用户名和密码,数据参考的就是auth_user表,并且必须是管理员用户才能进入【二】创建超级用户(管理员)......
  • python计算机毕设【附源码】汉服文化管理系统(django+mysql+论文)
    本系统(程序+源码)带文档lw万字以上  文末可获取本课题的源码和程序系统程序文件列表系统的选题背景和意义选题背景:汉服,作为中国古代汉族传统服饰的总称,承载了丰富的历史文化遗产和审美价值。近年来,随着国民文化自信心的提升和传统文化复兴的浪潮,汉服文化逐渐走进了公众的......
  • 【26.2】Django框架之settings核心配置项
    【一】前言【1】引言Django的默认配置文件中,包含上百条配置项目其中很多是我们‘一辈子’都不碰到或者不需要单独配置的这些项目在需要的时候再去查手册。【2】强调配置的默认值不是在settings.py文件中!不要以为settings.py中的配置值就是默认值,参考前文。settings.py......
  • Django单程序运行
    1、增加环境变量并且配置#确保运行在最model类之前importosimportdjangoos.environ.setdefault('DJANGO_SETTINGS_MODULE','SmsProject.settings')django.setup()2、如果使用Pycharm还需要做如下配置3、运行程序importosimportdjangoos.environ.setdefault(......
  • 物流系统django版本
    1,创建modelspyfromdjango.dbimportmodelsclassGoods(models.Model):  id=models.AutoField(primary_key=True)  name=models.CharField('货物名称',default='',max_length=50)  source=models.CharField('渠道',max_length=......
  • Java/Mysql数据库+django学生就业管理系统 24237(免费领源码)计算机毕业设计项目推荐上
    学生就业管理系统摘 要随着社会的快速发展和人们生活水平的不断提高,旅游已逐渐成为人们生活的重要组成部分,用户能够获取旅游信息的渠道也随信息技术的广泛应用而增加。大量未经过滤的信息在展示给用户的同时,也淹没了用户真正感兴趣的信息。为了方便用户快速定位自己感兴趣......
  • python计算机毕设【附源码】便利店收银管理系统(django+mysql+论文)
    本系统(程序+源码)带文档lw万字以上  文末可获取本课题的源码和程序系统程序文件列表系统的选题背景和意义选题背景:随着社会的发展和经济的进步,便利店作为一种新型的零售业态在城市中迅速崛起。便利店以其便捷的地理位置、丰富的商品种类和高效的服务赢得了消费者的青睐。......