Django框架之csrf跨站请求
2116 字
11 分钟
Django框架之csrf跨站请求
- 1纯手撸Web框架
- 2Python框架初识
- 3Django框架初识
- 4Django框架安装
- 5Django框架入门之小白必会三板斧
- 6Django便捷函数shortcuts
- 7Django框架入门之静态文件
- 8Django的静态文件
- 9Django框架入门之request对象
- 10Django框架入门之ORM操作
- 11Django框架之生命周期流程图
- 12Django框架之路由层
- 13Django框架之视图层
- 14Django框架之模板层
- 15Django框架之模型层
- 16图书管理系统
- 17Ajax基础操作
- 18Ajax进阶操作
- 19JS确认插件补充
- 20Django框架之序列化组件serializers
- 21Django框架之批量插入数据
- 22Django框架补充之分页器推导
- 23Django框架之Form组件
- 24Django框架Form组件之常用字段及插件
- 25Django框架Form组件之渲染HTML代码
- 26Django框架Form组件之渲染错误信息
- 27Django框架Form组件之钩子函数(Hook)
- 28Django框架Form组件之源码
- 29Django框架Form组件之模型表单ModelForm
- 30Django表单API详解
- 31Django框架之Cookie和Session
- 32Django框架之会话session补充
- 33Django框架之CBV添加装饰器的三种方式
- 34Django框架之中间件引入
- 35Django框架之中间件思想
- 36Django框架之csrf跨站请求本文
- 37Django框架之auth模块
- 38Django框架之settings源码
- 39Django框架之settings配置
- 40Django框架之settings核心配置项
- 41RBAC权限系统
- 42前端基础之URL编码
【一】跨站请求伪造介绍
【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_exemptdef 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 Viewfrom django.views.decorators.csrf import csrf_protect, csrf_exemptfrom 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 Viewfrom django.views.decorators.csrf import csrf_protect, csrf_exemptfrom 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 Viewfrom django.views.decorators.csrf import csrf_protect, csrf_exemptfrom 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 Viewfrom django.views.decorators.csrf import csrf_protect, csrf_exemptfrom 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")支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!
相关文章智能推荐
1
C 语言发展史
编程语言了解 C 语言从 BCPL、B 语言到现代标准 C 的发展历程、核心特点与应用领域。
2
C 语言开发环境的安装与配置
编程语言在 Windows、Linux 与 macOS 上安装 C 工具链,配置编辑器,并编译运行第一个 C 程序。
3
C 语言初识:程序运行机制与基本结构
编程语言认识 C 程序从源代码到运行的完整流程,以及基础语法和程序的基本结构。
4
C 语言基础:注释、关键字、变量与数据类型
编程语言学习 C 语言的注释、关键字、标识符、常量、变量和基本数据类型等基础知识。
5
C 语言数据类型
编程语言理解 C 语言的数据类型体系,包括基本类型、整数类型、浮点类型和逻辑类型。
随机文章随机推荐














