防止重复请求攻击

Posted jarvisjin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了防止重复请求攻击相关的知识,希望对你有一定的参考价值。

今天发现自己项目一个漏洞:先为一账户充值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文档。

以上是关于防止重复请求攻击的主要内容,如果未能解决你的问题,请参考以下文章

如何有效防止API的重放攻击(转自阿里云)

.NET添加时间戳防止重放攻击

重放攻击

重放攻击

重放攻击(Replay Attacks)

重放攻击(Replay Attacks)