Django下防御Race Condition
目录
漏洞原因
环境搭建
复现
A.无锁无事务时的竞争攻击
B.无锁有事务时的竞争攻击
防御
A.悲观锁加事务防御
B.乐观锁加事务防御
总结
漏洞原因
Race Condition 发生在多个执行实体(如线程、进程)同时访问共享资源时,由于执行顺序的不确定性,导致程序的最终行为依赖于这些实体的执行时序。如果程序逻辑未正确处理这种并发访问,就会产生意外的结果。
环境搭建
从github上下载源码GitHub - phith0n/race-condition-playground: Playground for Race Condition attack
然后拖到虚拟机上解压
unzip race-condition-playground-main.zip
之后重命名并修改.env.default文件
root@sxc-ubuntu:~/race-condition-playground-main# mv .env.default .env
安装依赖的库
pip3 install -r requirements.txt 依赖库python3 manage.py migrate 生成数据表python3 manage.py collectstatic 生成前端代码python3 manage.py createsuperuser 添加用户python3 manage.py runserver 0.0.0.0:8080 启动
最后还要修改一下templates目录下的form.html,将form表单的提交方式修改为form-data流
复现
A.无锁无事务时的竞争攻击
class WithdrawView1(BaseWithdrawView):success_url = reverse_lazy('ucenter:withdraw1')//form表单验证//已经通过验证def form_valid(self, form):amount = form.cleaned_data['amount']self.request.user.money -= amountself.request.user.save()models.WithdrawLog.objects.create(user=self.request.user, amount=amount)return redirect(self.get_success_url())
整个操作没有使用事务,也没有加锁,理论上存在Race Condition漏洞。
1.登录后台
http://192.168.217.128:8080/admin
2.在user模块添加Money
3.进入ucenter提现页面
http://192.168.217.128:8080/ucenter/1/
4.点击提交使用burp抓包,发送到repeater模块。(注意,要将拦截到的包drop掉,不然10块钱直接没了,没法测试了)。然后将包内容复制到Yakit上的WebFuzzer下的request里面,并设置好重复发包数和并行线程数。
5.点击发送请求,我们会在request模块右边,看到响应结果,很幸运一次就成功了
在前端页面的withdrow logs模块也看到了日志信息
竞争成功
B.无锁有事务时的竞争攻击
新编写一个`WithdrawView2`,加上`@transaction.atomic`修饰符:成功则成功,失败则回滚class WithdrawView2(BaseWithdrawView):success_url = reverse_lazy('ucenter:withdraw2')@transaction.atomicdef form_valid(self, form):amount = form.cleaned_data['amount']self.request.user.money -= amountself.request.user.save()models.WithdrawLog.objects.create(user=self.request.user, amount=amount)return redirect(self.get_success_url())
同样使用Yakit测试
发现结果并没有什么区别
防御
A.悲观锁加事务防御
Django在ORM里提供了对数据库Select for Update的支持,结合Where语句,可以实现行级的锁。 使用SELECT FOR UPDATE
获取到的数据库记录,不会再被其他事务获取。
这样就可以保证我们在同一个事务内执行的操作的原子性,这是一个典型的悲观锁。
“悲观锁”的意思是,我们先假设其他线程会修改数据,所以在操作数据库前就加锁,直到当前线程释放锁后,其他线程才能再次获取这个锁。
乐观锁通常通过版本号(Version)或时间戳(Timestamp)实现。
我们使用`select_for_update()`来实现一个`WithdrawView3`:class WithdrawView3(BaseWithdrawView):success_url = reverse_lazy('ucenter:withdraw3')def get_form_kwargs(self):kwargs = super().get_form_kwargs()kwargs['user'] = self.userreturn kwargs@transaction.atomicdef dispatch(self, request, *args, **kwargs):self.user = get_object_or_404(models.User.objects.select_for_update().all(), pk=self.request.user.pk)return super().dispatch(request, *args, **kwargs)def form_valid(self, form):amount = form.cleaned_data['amount']self.user.money -= amountself.user.save()models.WithdrawLog.objects.create(user=self.user, amount=amount)return redirect(self.get_success_url())
对于当前这个场景,我们再次尝试使用Yakit进行竞争攻击:
可见,此时返回包只有一个302响应了, 这意味着程序是按照预期运行,没有发生Race Condition问题。
B.乐观锁加事务防御
我们观察上述的WithdrawView3
代码,其实会发现一个问题,如果有大量读操作的场景下,使用悲观锁会有性能问题。因为每次访问这个view都会锁住当前用户对象,此时其他要使用这个用户的场景(如查看用户主页)也会卡住。
另外,也不是所有数据库都支持select for update
,我们也可以尝试使用乐观锁来解决Race Condition的问题。
乐观锁的意思就是,我们不假设其他进程会修改数据,所以不加锁,而是到需要更新数据的时候,再使用数据库自身的UPDATE操作来更新数据库。因为UPDATE语句本身是原子操作,所以也可以用来防御并发问题。
我们新增一个`WithdrawView4`:class WithdrawView4(BaseWithdrawView):success_url = reverse_lazy('ucenter:withdraw4')@transaction.atomicdef form_valid(self, form):amount = form.cleaned_data['amount']rows = models.User.objects.filter(pk=self.request.user, money__gte=amount).update(money=F('money')-amount)if rows > 0:models.WithdrawLog.objects.create(user=self.request.user, amount=amount)return redirect(self.get_success_url())
使用Yakit进行测试,只有一次302返回:
乐观锁的优点就是不会锁住数据库记录,也就不会影响其他线程查询该用户。
总结
悲观锁 和 乐观锁 是两种常见的并发控制机制,用于解决多个事务同时访问和修改同一数据时可能引发的冲突问题。它们的核心区别在于对并发冲突的处理方式。
相关文章:

Django下防御Race Condition
目录 漏洞原因 环境搭建 复现 A.无锁无事务时的竞争攻击 B.无锁有事务时的竞争攻击 防御 A.悲观锁加事务防御 B.乐观锁加事务防御 总结 漏洞原因 Race Condition 发生在多个执行实体(如线程、进程)同时访问共享资源时,由于执行顺序…...
Vue 项目中,.env文件怎么用?
在 Vue 项目中,.env 文件用于存储环境变量,不同的环境(如开发环境、测试环境、生产环境)可以使用不同的 .env 文件来管理对应的配置信息。以下是关于 Vue 项目中 .env 文件的详细使用方法: 1. 项目创建 确保你已经使…...
LeetCode hot 100—爬楼梯
题目 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 示例 示例 1: 输入:n 2 输出:2 解释:有两种方法可以爬到楼顶。 1. 1 阶 1 阶 2. 2 阶 示例…...

【js逆向】
地址:aHR0cHM6Ly93d3cud2VpYm90b3AuY24vMi4wLw f12进入 debugger,过debugger 查看预览数据 全局搜索 请求网址中的 api.weibotop.cn 在下方疑似找到了加密和解密的函数 断点调试 控制台输出 那个n就是 常见的 cryptoJs库 const cryptoJs require(cry…...
论文阅读-秦汉时期北方边疆组织的空间互动模式与直道的定位(中国)
论文英文题目:A spatial interaction model of Qin-Han Dynasty organisation on the northern frontier and the location of the Zhidao highway (China) 发表于:journal of archaeological science,影响因子:3.030 论文主要是…...
DirectX12(D3D12)基础教程四 入门指南
本章主要讲了些D3D12概念和理论,对第一、二章相关概念的补充和纠正,要的理解D3D12概念和理论基础,结合代码加深理解。 命令队列和命令列表 为了实现渲染工作的重用和多线程缩放, 在 D3D12 中,做了三个重要方面不同于 …...
C语言:确定进制
题目: 6942对于十进制来说是错误的,但是对于13进制来说是正确的。即, 6(13) 9(13) 42(13), 而 42(13)4131213054(10)。 任务是写一段程序,读入三个整数p、q和 r,然后确定一个进制 B(2<B<40) 使得 p q r。 如果…...
如何在 Windows 10 启用卓越性能模式及不同电源计划对比
在使用 powercfg -duplicatescheme 命令启用 “卓越性能模式”(即 Ultimate Performance 模式)之前,有几个前提条件需要注意: 前提条件: 系统版本要求:卓越性能模式 仅在 Windows 10 专业版 或更高版本&a…...
Unity Android出包
Unity Android出包 1.Android Studio版本 不能高于Unity的版本 2.so库 这个库需要自己拷贝到Android工程当中 3.JDK版本太老 编译可以正常,但无法运行 File->ProjectStructure->SDK Location->Gradle Setting->Gradle JDK->X:/Android Stuido/jre …...

Day04 模拟原生开发app过程 Androidstudio+逍遥模拟器
1、用Androidstudio打开已经写好了的music项目 2、逍遥模拟器打开apk后缀文件 3、在源文件搜索关键字 以后的测试中做资产收集...

2025人工智能AI新突破:PINN内嵌物理神经网络火了
最近在淘金的时候发现基于物理信息的神经网络(简称PINN)也是个研究热点,遂研读了几篇经典论文,深觉这也是个好发论文的方向,所以火速整理了一些个人认为很值得一读的PINN论文和同学们分享。 为了方面同学们更好地理解…...

通义万相 2.1 携手蓝耘云平台:开启影视广告创意新纪元
💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…...

【计算机网络】深入解析 HTTP 请求中的 header 类型:Cookie 的概念、特点和应用场景:登录和用户认证
网络原理— HTTP 请求“报头”(header) Cookie 是什么 HTTP报头中的Cookie,用大白话来说,就像你去餐厅吃饭时拿到的一张会员卡: 初次访问 (清除该网站的所有 Cookie 后重新访问该网站,效果相同): 当你第一次访问一个网…...

LeetCode 解题思路 11(Hot 100)
解题思路: 若相等: 直接返回 true。若当前元素大于目标值: 由于列递增,当前列下方所有元素均大于目标值,故排除该列(向左移动)。若当前元素小于目标值: 由于行递增,当前…...

警惕AI神话破灭:深度解析大模型缺陷与禁用场景指南
摘要 当前AI大模型虽展现强大能力,但其本质缺陷可能引发系统性风险。本文从认知鸿沟、数据困境、伦理雷区、技术瓶颈四大维度剖析大模型局限性,揭示医疗诊断、法律决策等8类禁用场景,提出可信AI建设框架与用户防护策略。通过理论分析与实操案…...

文件系统调用(上) ─── linux第17课
目录 linux 中man 2和man 3的区别 文件内容介绍 C语言文件接口 示例: 输出信息到显示器,你有哪些方法 总结: 系统文件I/O 文件类的系统调用接口介绍 示例 open 函数具体使用哪个,和具体应用场景相关, write read close lseek ,类比C文件相关接…...
go 标准库包学习笔记
本博文包含了go的math,net/http,fmt,io,csv,time.Time,strconv,strings,sync.Pool的学习,笔记多是其实战如何用,而非简单的函数式的讲解,可谓是收藏佳作,不时翻翻。 文章目录 1、math2、net/http3、fmt4、…...

Unity摄像机跟随物体
功能描述 实现摄像机跟随物体,并使物体始终保持在画面中心位置。 实现步骤 创建脚本:在Unity中创建一个新的C#脚本,命名为CameraFollow。 代码如下: using UnityEngine;public class CameraFollow : MonoBehaviour {public Tran…...
线程管理操作
1.创建两个线程,,分支线程1拷贝文件的前一部分,分支线程2拷贝文件的后一部分 #include <head.h>#define SRC_FILE "./1.txt" #define DST_FILE "./2.txt" #define BUFFER_SIZE 4096struct copy_args {long start;l…...

VSCode 2025最新前端开发必备插件推荐汇总(提效指南)
🌟前言: 如果你是一名前端开发工程师,合适的开发工具能大大提高工作效率。Visual Studio Code (VSCode) 凭借其轻量级、高扩展性的特点,已成为众多前端开发者在win系电脑的首选IDE。 名人说:博观而约取,厚积而薄发。—…...

测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...

微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...

使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...

MFC 抛体运动模拟:常见问题解决与界面美化
在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...