๐งช Labs โบ Business Logic
Race Conditions
Severity: MediumFire the same action many times at once and slip through the gap before the check catches up.
What it is
Many apps check a condition and then act on it as two separate steps. If requests arrive close enough together, several can pass the check before any of them updates the state โ the classic time-of-check to time-of-use gap.
That turns 'use a coupon once' into use it many times, 'withdraw up to your balance' into overdraw, 'one vote' into many.
The bug is concurrency the developer didn't account for, not a malformed input.
How to approach it
- Find an action that checks a limit and then changes state โ a redemption, a transfer, a one-time claim.
- Send many copies of the same request simultaneously so they overlap inside that window.
- Compare the outcome to the intended single-use behaviour.
- Reason about where the check and the update should have been a single atomic step.
Your task
Exceed a one-time limit by exploiting the window between the check and the update.
โถ Access the labOpens your hosted RatCTF instance. Work on it directly โ there's nothing to submit here; you'll know when you've solved it.
How to prevent it
- Make the check-and-update atomic (database constraints, row locks, or transactions).
- Enforce idempotency on sensitive actions.
- Don't rely on application-layer checks for invariants the database can guarantee.
More Business Logic labs
- Mass Assignment โ Send fields the form never showed you, and the server saves them anyway.