Earlier lessons attacked rules that were enforced in the wrong place — on the client instead of the server. This lesson attacks a rule that is enforced in the right place but at the wrong time.
A race condition is a flaw in which the correctness of an operation depends on the timing of concurrent executions. Run the same requests one after another and everything is fine; run them at the same instant and the result is something the designer never intended — most often an action meant to happen once happening many times.
The classic shape is time-of-check to time-of-use (TOCTOU). Code does two things as separate steps:
- It checks a condition — "is this coupon unused?", "is there stock left?", "is the balance sufficient?".
- It then acts on the result — "mark it used", "decrement the stock", "debit the balance".
Between the check and the act there is a gap. If a second request slips into that gap, both requests read the same "before" state, and both act — even though only one of them should have. Fifty concurrent requests can pay out a one-time coupon fifty times.
Prerequisites: business-logic-flaws for server-side rule enforcement and intercepting-proxies for request replay. This lesson adds concurrency: every individual request may be valid, but the timing makes the result unsafe.
In this lesson you will:
- Understand why code that looks correct read top-to-bottom can still be wrong under concurrency.
- See the check-then-act gap and how overlapping requests exploit it.
- Use Attack Lab to simulate many concurrent copies of one request and compare vulnerable handling with the atomic fix.
- Reason about why the durable fix is an atomic server-side operation, never a disabled button.
Estimated time: 10 to 15 minutes.
When you are ready, send the Continue signal.