第 6 章 · 06 业务逻辑与竞争条件 本节摘要:业务逻辑漏洞利用预期功能违反领域不变量——不付钱就拿货、突破限额、保留特权、绕过审批;竞争条件则让并发请求绕过原子性检查——重复消费、重复退款、突破单次限制。两者紧密交织:许多业务逻辑漏洞只在并发或重放下才暴露(双花、超额退款、限额切片),因此本节合并讲解。业务逻辑不靠 payload,靠的是「对业务建模」——先画出状态机与不变量(价值守恒、唯一性、单调性、互斥性),再用「跳步/重放/乱序/并发/时间窗/数值边界」去逼出每一条缺失的服务端守卫。
本节摘要:业务逻辑漏洞利用预期功能违反领域不变量——不付钱就拿货、突破限额、保留特权、绕过审批;竞争条件则让并发请求绕过原子性检查——重复消费、重复退款、突破单次限制。两者紧密交织:许多业务逻辑漏洞只在并发或重放下才暴露(双花、超额退款、限额切片),因此本节合并讲解。业务逻辑不靠 payload,靠的是「对业务建模」——先画出状态机与不变量(价值守恒、唯一性、单调性、互斥性),再用「跳步/重放/乱序/并发/时间窗/数值边界」去逼出每一条缺失的服务端守卫。竞争条件不靠复杂 payload,靠的是「把每一次读-改-写与多步工作流都当作对抗性并发」——HTTP/2 多路复用、last-byte 同步、连接预热,把 N 个本该只成功 1 个的请求挤进同一个窗口。本节讲透攻击面(金融逻辑、账户生命周期、配额限额、事件驱动流)、关键漏洞(状态机滥用、并发与幂等、数值与货币、限额与库存、退款与争议、特性门槛)、竞争窗口识别与利用(请求同步、幂等绕过、原子性缺口、跨服务竞态、速率限制与配额、乐观并发规避、DB 隔离、分布式锁),以及业务逻辑+竞争+IDOR+CSRF 的链式放大。
内容来源:原项目知识包
strix/skills/vulnerabilities/{business_logic,race_conditions}.md,汉化并套用体系化模板合并。
⚠️ 仅限授权测试:本节所有 payload 与技术仅用于你自己的应用或有书面授权的渗透测试。未经授权对他人系统使用这些技术是非法的。
阅读完本节,你应当能够:
业务逻辑与竞争条件共享同一组「易感工作流」,区别在于是单请求就能触发(纯逻辑),还是需要并发/重放才触发(竞争)。
易感业务面:
高价值目标:
竞争条件专属攻击面:
💡 核心心法:业务逻辑安全 = 在对抗性的排序、时序、输入下强制领域不变量;并发安全 = 每一条会改状态的路都要有原子性、正确隔离、幂等。任一步骤信任客户端或先前步骤,就预期被滥用。
工作流映射:从 UI 与代理/网络日志推导端点;映射隐藏/未文档化 API,尤其 finalize/confirm;识别 token/标志(stepToken/paymentIntentId/orderStatus/reviewState/approvalId),测跨用户/会话复用;记录不变量(价值守恒=账本余额、唯一性=幂等、单调性=非递减计数器、互斥性=单一活跃订阅)。
输入面:隐藏字段与客户端计算的总数(服务器必须基于可信源重算);替代编码与形态(数组 vs 标量、意外键的对象、null/空/0/负、科学计数法);业务选择器(货币、locale、时区、税区——触发取整与规则集变化)。
状态与时间轴:重放(重提交陈旧的 finalize/confirm);乱序(finalize 先于 verify、refund 先于 capture、cancel 在 ship 之后);时间窗(月末/日终切换、夏令时、宽限期、试用过期边界)。
信号:串行请求失败但并行成功;重复行、负计数器、超额发行、聚合不一致;同时 vs 串行请求的响应形态/时延不同;审计日志乱序;同一意图多个 2xx;缺失或重复的 correlation ID。
状态机滥用:经直接 API 跳步或乱序;验证服务器在每个转换上强制前置条件;用改过的参数重放前序步骤(如审批后、capture 前换价格);把单个受限动作拆成多个阈值以下的子动作(限额切片)。
数值与货币:浮点 vs decimal 取整;边界上有利于攻击者的取整/截断;跨币套利(A 币买入、B 币按陈旧汇率退款);逐项 vs 逐单税额取整;负金额、零价、免运费阈值、最小/最大护栏。
配额、限额与库存:off-by-one 与基于时间的重置(UTC vs 本地);在 T-1s 预热、T+1s 触发;预留/持有泄露(预留多个、完成一个、释放未强制);缺强一致性的分布式计数器导致双消费。
退款与争议:双重退款(UI + 支持工具;部分退款之和超过 captured 金额);消费后退款(已下载数字商品、已发货)因缺消费后检查。
特性门槛与角色:客户端或边缘强制的特性开关,核心服务没有——猜测开关名或回退到默认启用;角色转换留下陈旧能力(降级后保留 premium;降职后保留 admin 端点)。
事件驱动 saga:saga/补偿间隙——触发补偿却无原始成功,或执行两次成功却无补偿;Outbox/Inbox 缺幂等 → 重复下游副作用;cron/backfill 在请求时授权之外运作,广泛改状态。
微服务边界:跨服务假设不匹配——一个服务校验总额,另一个信任 line item,在调用间改动;头部信任(内部服务信任 X-Role/X-User-Id);部分失败窗口——两阶段动作中阶段 1 提交、阶段 2 未执行,留下可利用的中间态。
多租户隔离:租户作用域的计数器与信用在 where 子句中不带租户键 → 跨组织渗漏;管理聚合视图因缺逐租户强制,允许影响他租户的动作。
请求同步:
幂等与去重绕过:
原子性缺口:
跨服务竞态:saga/补偿时序间隙;eventual consistency 窗口(在服务 A 写入可见前于服务 B 行动);at-least-once 投递却无幂等消费者 → 重试风暴重复副作用。
速率限制与配额:按 IP 或按连接强制 → 多 IP/会话绕过;计数器更新非原子或分片不一致 → 在传播前发突发。
乐观并发规避:省略可选的 If-Match/ETag;若服务器忽略则提供陈旧 version;version 字段被接受却未在所有路径校验(GraphQL vs REST)。
数据库隔离:利用 READ COMMITTED/REPEATABLE READ 异常(幻读、非可串行化);upsert 竞态——用带 ON CONFLICT/UPSERT 的唯一索引,或利用朴素存在性检查;锁粒度问题(行 vs 表;仅进程内持有的应用锁)。
分布式锁:无 NX/EX 或 fencing token 的 Redis 锁允许多个赢家;单节点内存锁 → 打其他节点/区域绕过。
特殊上下文:GraphQL(并行 mutation 与批量操作可能绕过逐 mutation 守卫;持久化查询与 aliases 在单请求藏多个状态变更);WebSocket(逐消息授权与幂等必须成立;并发 emit 在仅握手校验时创建重复);文件与存储(多分片上传的并行 finalize/complete;并发复用预签名 URL);认证流(并发消费一次性 token——重置码、magic link——铸造多个 session;验证 consume 是否原子)。
X-HTTP-Method-Override)。💡 绕过的本质:业务逻辑——校验常在某一条代码路径(content-type/方法/通道)上缺失,换一条即绕;竞争——限流按错误维度(IP/连接/请求)计,且竞态窗口常因后端依赖变慢而加宽,主动制造延迟是核心手段。
常见误报:
⚠️ 业务逻辑与竞争的影响常被低估——它们不触发扫描器,却能直接造成资金损失与监管违规。始终用「持久状态变更 + 权威来源证据」量化影响,而非停留在「看起来不对」。
下一节,我们看客户端与其它——开放重定向、原型污染、信息泄露、子域接管、不安全文件上传、LLM 提示注入,把本章的剩余高价值漏洞一次性收束。