码迷,mamicode.com
首页 > 其他好文 > 详细

防止重复请求攻击

时间:2019-02-25 18:13:32      阅读:185      评论:0      收藏:0      [点我收藏+]

标签:count   查询   导致   时长   校验   请求   取数   释放   sql   

今天发现自己项目一个漏洞:先为一账户充值100元,然后瞬间发送10次提现请求(都是提现100,提现接口是有做余额不足校验的),其中大约有四五次都是成功的,剩下的会报余额不足。期望是,只有一次可以成功完成提现,分析到能部分请求能通过余额不足校验原因是,由于是瞬间发出的提现请求,这些请求中拿到的余额数据都是余额扣减之前的数据。

以上场景可以提炼出两个关键步骤:

  1. 查询余额并校验,select * from account where user_id = 123;
  2. 扣减余额并支付,update account set balance...

根据以上步骤,可知:1.在两条SQL语句执行的中间这段时间,由于重复请求攻击,可能会出现多次请求的第一步操作成功,并继续执行第二步,最后导致资金损失。2.由于第一步操作是查询操作,没有数据库会限制重复读取数据,数据库层面是没有可能解决这个问题的,所以不用在这个上面浪费时间。

目前的解决方案是:为接口上锁。已经有人做了轮子,比如redis-lock。以用户ID为key,某个uuid为值。将类似提现这样的接口上锁。同一用户在访问添加了该中间件的接口时,第一次没有执行完毕,拒绝执行第二个请求。第一次执行完毕时,释放锁,即清除redis缓存的键值对。同时可设定,缓存时长,以防中途宕机,锁未释放等问题。具体实现可以参考npm包redis-lock文档。

防止重复请求攻击

标签:count   查询   导致   时长   校验   请求   取数   释放   sql   

原文地址:https://www.cnblogs.com/jarvisjin/p/9969322.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!