并发请求导致的业务处理安全风险及解决方案
来源:互联网 发布:flash cs3 mac 中文 编辑:程序博客网 时间:2024/05/19 17:06
0x00 背景
一段简单的购买程序,看起来没有任何问题。
剩余余额、商品库存、购买权限等判断面面俱到,从头到脚包装的严严实实。
但是为何人一多就频频漏点呐?何解?
0x01 问题分析
还是以商城购买为例,商城网站是web程序和数据库两部分,业务处理流程:
#!shell用户金额是否大于商品价格—>商品库存是否充足—>购买操作:生成订单—>扣除用户金额—>商品库存减1
流程的每一部分都是web与数据库打交道,查询或者操作数据库。
程序示例(PHP+MySQL)
#!php$goods=$db->FirstRow("SELECT * FROM ".Tb('goods')." WHERE goods_id='{$goods_id}'");if(empty($goods)) ShowError('商品不存在');/* 金额是否充足 */if($user->money<$goods['price']) ShowError('金额不足,请充值');/* 商品库存 */if($goods['num']==0) ShowError('库存不足');/* 购买操作 begin *///生成订单CreateOrder($goods,$user,time());$user->Update('money'=>$user->money-$goods['price']); //用户金额减少$db->Execute("UPDATE ".Tb('goods')." SET num=num-1 WHERE goods_id='{$goods_id}'");//商品库存-1ShowSuccess('购买成功');/* 购买操作 end */
正常来看这个业务处理是没有问题的,下面想象下多人同时购买(并发请求,如秒杀活动)的情境可能会引发的问题?
如果一个用户同时有两次购买请求,一次购买已进行到添加订单但未扣除用户金额,另一次购买在第一步用户金额判断便不准确了。
当商品库存仅为1时,同时有多个请求,而当前没有一个请求走到商品库存减少位置,多次购买都能成功,而商城却无货可发。
总结来说,当有大量的购买操作同时进行,如果数据库的处理速度跟不上程序的请求速度,就会出现判断不准确的问题,造成用户以单个商品的金额购买多个商品、某些用户付款了但得不到商品等,算是一个安全风险。
0x02 解决方案:
核心思想:将一次业务处理流程(如购买操作)作为一个最小操作单元,同一时间只能有一个操作。
1. 整个操作加内存锁。如在memcache里,开始购买时设置购买状态为进行中,购买结束后清除购买状态,程序开始时即从memcache里判断是否有正在进行的购买操作,如有则退出。2. 限制每个用户的购买间隔,如10秒内仅允许购买一次,最好也是放在内存里。3. 当然,优化数据库及程序以加快处理速度也是有必要的。
解决方案程序示例(PHP+MySQL+Memcached)
#!php/** * 通过memcache解决并发购买问题 */$goods=$db->FirstRow("SELECT * FROM ".Tb('goods')." WHERE goods_id='{$goods_id}'");if(empty($goods)) ShowError('商品不存在');$mmc=memcache_init();$lastBuyTime=$mmc->get('lastBuyTime_'.$user->userId);if($lastBuyTime>0 && $lastBuyTime>time()-10) ShowError('10秒内只能进行一次购买');$buying=$mmc->get('buying');if($buying==1) ShowError('有正在进行的购买,请稍候');/* 金额是否充足 */if($user->money<$goods['price']) ShowError('金额不足,请充值');/* 商品库存 */if($goods['num']==0) ShowError('库存不足');/* 购买操作 begin *///生成订单CreateOrder($goods,$user,time());$user->Update('money'=>$user->money-$goods['price']); //用户金额减少$db->Execute("UPDATE ".Tb('goods')." SET num=num-1 WHERE goods_id='{$goods_id}'");//商品库存-1/* 购买操作 end */$mmc->set('buying',0);$mmc->set('lastBuyTime_'.$user->userId,time());ShowSuccess('购买成功');
http://drops.wooyun.org/papers/831
0 0
- 并发请求导致的业务处理安全风险及解决方案
- 并发请求导致的业务处理安全风险及解决方案
- Apache流量猛增,并发过高导致问题的处理解决方案
- Apache流量猛增,并发过高导致问题的处理解决方案
- Apache流量猛增,并发过高导致问题的处理解决方案
- 综合业务分析高并发及解决方案
- 业务安全信息风险评估
- 构建一个安全的软件系统时,可能遇到的风险及解决方案(未完)
- 【微信小程序】下拉加载多次请求的解决方案,避免用户多次发起请求降低业务处理。
- 控制服务器处理请求的数量(高并发)-防止用户重复点击导致多次请求
- 搜索结果中“李鬼”导致的安全风险
- IIS处理并发请求时出现的问题及解决
- IIS处理并发请求时出现的问题及解决
- IE总出现"您的安全设置级别导致计算机存在安全风险”提醒的解决方法
- 并发处理业务
- tomcat处理请求导致页面出现ERR_CONNECTION_RESET错误解决方案
- 互联网业务安全之通用安全风险模型
- 互联网业务安全之通用安全风险模型
- Fortran从文件读入数据的规律
- 28 - 字符串的全排列和组合
- Remove Duplicates from Sorted List
- 51nod1051(最大子矩阵和)
- CUDA nvcc编译步骤简单讲解
- 并发请求导致的业务处理安全风险及解决方案
- 【HDU】5293 Tree chain problem【DP+LCA】
- C# 向指定线程发送消息
- 初识MVC框架
- eclipse 全局搜索
- 算法——贪心、穷举法
- 最小生成树(prim)
- 教你如何使用FastJson
- hdu5331--Sequence(数学)