条件竞争比较常见的例子是攻击者通过并发 https 请求而达到多次获奖、多次收获、多次获赠等非正常逻辑所能触发的效果。
漏洞代码示例
// 从DB里查询该用户剩余获奖次数,初始值为1 int remain_times = SelectRemainTimes(); if(remain_times > 0){ EarnRewards(); // 用户获得奖励 ClearRemainTimes(); // 在DB里把该用户的剩余获奖次数清零 }开发者的设计本意是只允许用户获得一次奖励,但当出现并发请求时,有可能出现请求 A 和请求 B 都刚好执行完第2行代码的情况,此时两个请求的 remain_times 都为1,也就是可以通过第4行代码的判断,获得两次奖励。
开发建议:
- 对关键(完整)逻辑加锁操作或把关键逻辑以队列任务的形式去进行处理。