上次介绍了一些常见的影响资金的 bug,由于篇幅原因,没有全部写完,这次接着来介绍资金相关还有可能出现 bug 的地方,当然,操作方式跟之前介绍的也略微不同。
充值指的是向应用程序充钱到自己的账号,欺骗充值指的就是欺骗应用程序说自己已经充值成功了,让自己的账号没有经过实际支付就增加余额。下面以小程序为例,来讲下怎么做到欺骗。
首先,看下小程序支付交互的流程:
↑↑小程序官方交互图↑↑
从上图可以看出,支付状态是由微信后台通知商户系统后,再由商户系统更新状态的。根据官方推荐的做法一般不会出什么幺蛾子,但是有些初学者不按套路来,直接在小程序收到支付结果中的回调函数中调用后端接口进行更新状态(小程序回调没有上图中画出),这就留下了祸根了。
我们可以尝试在发起支付接口后,不进行真实支付,通过模拟回调函数中调用的接口直接调用,看看订单的状态是否改变,如果真的改变了,余额新增了,那么恭喜你,找到一个大 bug 了。这种系统不是新手就是临时工开发的,毕竟这类 bug 现在已经少而又少,比较常见的案例是 0.01 元充 100 话费。
什么是超领?正常的话,一个拼手气红包每个人只可以领取一次,超领就是一个拼手气红包被一个人领了多次。这类 bug 分为两种,下面来说说怎么找:
第一种是比较低级的:用户能不能领取全由前端控制,后端不做校验,交互图如下:
从 UI 上看,找不出不出什么 bug 来,但是从接口上就很容易绕过,每次直接调用领取红包接口,就能实现不断的领取红包了。
这么来说,是不是后端加上校验就行了?话是这么说,但是也要看是怎么个校验法,如果是单纯在领取结果前的查下数据库是否领取就算校验的话,那就要留个心眼了。交互如下:
现在开始介绍第二种稍微高级一丢丢的超领方法:那就是并发请求。同时发起 10 个甚至 100 个请求,领取同一个红包,所有并发请求同一时间到达数据库判断的时刻,判断结果都是没有领取过,这样有概率再一次实现超领了。(怎么发起并发就不用做过多介绍了吧?)
这里,我推荐的是在数据库中的红包领取表中添加唯一约束,将红包 id 与领取人 id 设置为为唯一约束,这样插入领取信息的时候,数据库就会报错拉。当然我只是测试,没有实战过,有经验的开发者可以留言推荐更好的解决方法。
其实超额提现&并发提醒这两类 bug 是跟上面介绍的红包超领如出一辙的,只是场景不同而已。
超额提现的问题是出在:只由前端限制可提现金额,后端没有做任何校验,导致调用提现接口就能直接超额提现。
并发提现就是后端做了校验的前提下,通过并发同时调用提现接口 100 次,校验做的不好,公司的实际金额就这样被盗走了。
关于异常提现,我建议的是追加两种方案来应对:
看到这,各位可以去试一试自家的产品是否有被并发超领的情况咯,场景不限于:领红包、抽奖、提现等。
如果你有其他奇招,欢迎一起交流。