• 防止重复请求攻击


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

    查资料不过是偏门,撸源码才是脱离苦海的正道。
  • 相关阅读:
    Dubbo——服务目录
    Dubbo——服务调用过程
    Dubbo——服务引用
    Dubbo——服务发布原理
    Dubbo——SPI及自适应扩展原理
    Zookeeper——Watcher原理详解
    Zookeeper——基本使用以及应用场景(手写实现分布式锁和rpc框架)
    Zookeeper——分布式一致性协议及Zookeeper Leader选举原理
    分布式架构概述及设计
    设计之禅——访问者模式
  • 原文地址:https://www.cnblogs.com/jarvisjin/p/9969322.html
Copyright © 2020-2023  润新知