Skip to content
Field Detail
Platform PortSwigger Web Security Academy
Type Race Conditions
Difficulty Apprentice
Objective Apply the PROMO20 coupon multiple times simultaneously to bring the jacket's price below $50 and complete the purchase

Limit Overrun Race Conditions

The homepage showed a promo code:

For 20% off use code at checkout: PROMO20
Screenshot

I logged in as wiener:peter (balance: $50), added the jacket to the cart, and applied the coupon. Applying it a second time returned "Coupon already applied":

Screenshot

The backend logic is: check if already applied → apply discount → mark as applied. These three steps happen sequentially but not atomically. The race window sits between the check and the state update — if two requests both pass the check before either records usage, both apply the discount. Parallelism turns a one-time code into a repeatable one. The fix is atomicity, not rate limiting: a conditional database update with a uniqueness constraint that fails if the coupon is already recorded.

I sent the POST /cart/coupon request to Repeater, duplicated it 20 times, grouped the tabs, and used "Send group in parallel":

Screenshot

Most responses returned "Coupon already applied" but a few slipped through during the race window:

Screenshot

Results vary — the race window is real but non-deterministic. Server load, scheduling, and internal latency mean some parallel requests are still processed sequentially. Running 20 requests in parallel doesn't guarantee 20 successful applications; it increases the probability of at least a few slipping through. Burp's parallel send over HTTP/2 packs multiple requests into one TCP packet, eliminating network jitter — the remaining variance is server-side processing order.

Alternatively, Burp's "Trigger Race Conditions" custom action automates this:

Screenshot
Screenshot
Screenshot

Multiple successes confirmed. The jacket's price dropped to $15 — well below the $50 balance. Placing the order:

Screenshot

Lab solved

Resources