优惠卷类型漏洞---优惠卷的并发使用

优惠卷的并发使用 主要是在形成订单的那个数据包那里,进行并发,如果可以创建多个订单并且显示在前端页面,尝试刷新页面防止前端误报,若还是存在,则存在漏洞。基本到可以创建订单就差不多了,也可以尝试去支付,但最好金额不要太大。

漏洞的原理

这个漏洞属于条件竞争漏洞,核心本质是多个进程或线程同时争夺一个资源,最后的结果取决于一些"运气"(执行的先后顺序和微妙的时间差)。

后端服务器(Nginx,Apache HTTP Server,Tomcat)基本都是多线程(或进程)去处理请求的

当你并发几十个请求一起发送到后端服务器,后端服务器会并发的处理这些请求,但是并发并不是物理意义上的一起处理,是按照一定的顺序,先处理这个请求一部分,在处理这个请求一部分,这样循环的。

加上对于优惠卷使用的检查流程大概是这样的:先检查数据库这个用户是否有优惠卷,然后请求使用优惠券,最后才会修改数据库的数据。

这样就会导致每个请求和数据修改之间会有一个微妙的时间差,也就是TOCTOU(检查时与使用时之间的时序漏洞),在请求一通过了检查,但是还没有修改数据库的时候,这是如果轮转到了请求二,那因为此时还没有修改数据库,所以检查仍然通过,这就导致了优惠卷重复使用。

根据此原理,主要的修补方案有两种:数据库方面加锁 和 分布式锁。

一、数据库层面加锁

一般来说查询数据用的sql语句是

sql 复制代码
SELECT is_used FROM coupons WHERE id = 123

而修改查询语句使用FOR UPDATE就可以解决这个问题

sql 复制代码
SELECT is_used FROM coupons WHERE id = 123 FOR UPDATE

当线程1执行到这条查询的时候,数据库会把id=123这一行锁住,其他的线程查询会显示在使用,只有线程1完全完成才会把id=123这条放开,此时数据库已经更改完成,线程2去请求则不会出现条件竞争的情况

二、分布式锁

在如今的现实中通常都是分布式的高并发情况,一般会采用Redis做一个分布式锁

Redis是单线程的、基于内存的、高性能的键值对(Key-Value)数据库服务器

一般不会用普通数据库比如MySQL数据库,因为它们的数据都是存放在硬盘上的,读写硬盘涉及大量的I/O操作速度相对较慢,高并发很容易卡死;而Redis是全部存在内存(RAM)里的,读写速度比硬盘快成千上百倍,官方显示Redis一秒钟可以处理10万次以上的读写操作请求。而且Redis是单线程执行命令的,无论多少请求都得一个个处理,很适合做锁,但是因为现在都是分布式高并发,为了适应那些的速度,Redis的处理速度必须很快,不过好在Redis并不去处理很复杂的东西,只是快速判断是否存在该键值对,有就等待或丢弃,没有就创建然后返回给后台的分布式服务器去执行服务,执行完后再回Redis销毁该键值对。

比如说你并发了50个请求,然后Redis会先让第一个请求进去,然后根据用户或者商品创建一个key,比如是按照用户创建的,那第二个请求进入的时候会发现已经创建了一个改用户的key,此时就会停止,停止后有两种可能(看后端开发式怎么写的),一是直接返回错误,二是等待每隔一段时间再去请求直到空闲,然后再去处理第二个请求。但是不管哪一种,都不再存在条件竞争,在key一样的情况下会被强制等待或丢弃。

整体的流程大概是这样的

Redis的锁,颗粒度很小很精准,所住的是具体某个用户的特定资源,而不是整个业务。而且锁的时间相对于整个的过程来说时间很短。

Redis只锁同键,不锁异键。

当然Redis锁什么也很有思考,比如购物时锁的如果是商品ID,那全网购买这个商品的用户都会被强制等待,就算你用bp的Turbo Intruder也没用,因为你并发多少次也都是那个商品ID;但是如果他锁的是用户的ID,就可以尝试用多个用户并发去尝试,因为他锁的是用户ID,那多个不同的用户并发就不会受到Redis锁的影响,就回去同时去向底层的MySQL数据库去扣库存(多个线程并发扣)就可能导致最后被扣成负数。

这些就是关于优惠卷并发使用的一些原理,当然上述说的都是可能成功,并发和网速的关系也很大,网速快成功概率和成功并发的数量都会更多(因为是在短时间内发大量包,网速越快,发的越多,就越可能抓住 TOCTOU 也就是检查和使用之间的这个时间差)。

相关推荐
斯内普吖22 分钟前
(开源)线上花店系统实战指南 基于 Java + SSM + Vue + MySQL
java·vue.js·mysql·开源
梦帮科技1 小时前
Linux 内存取证学与 Rootkit 猎杀——Volatility 核心剖析与内核隐藏模块逆向清除
linux·运维·服务器·神经网络·算法·网络安全
梦帮科技2 小时前
Web 漏洞攻防深度:WAF 规则逃逸技术(畸形分块传输、双重编码)与对抗加固
linux·前端·网络安全·ssl·web
tryxr2 小时前
数据库如何通过 MVCC 实现隔离性
数据库·mysql·mvcc·隔离性
sbjdhjd3 小时前
从 preg_replace 规则到缓存绕过:一次授权 PHP 防护实验中的图片载荷、回调检测与哈希碰撞复盘
网络安全·数据挖掘·php·文件包含·宝塔·哈希·火绒
白帽攻防录3 小时前
SRC 挖洞:DHCP 服务器上的四个 UAF,内网原生 RCE 怎么打域管
运维·服务器·网络安全·内网安全
yeflx3 小时前
Ubuntu22.04安装Mysql Workbench
数据库·mysql·adb
一支蜉蝣3 小时前
Day25 XD安全笔记 安全开发-PHP 应用&文件管理模块&包含&上传&遍历&写入&删除&下载&安全
笔记·网络安全·php
夜雪一千3 小时前
MySQL 自增 ID 的底层原理与坑点
android·mysql·adb
for_ever_love__4 小时前
半同步复制:数据安全和服务可用之间怎么权衡
redis·mysql·缓存·一致性·数据·半同步复制·方式