๐Ÿงช Labs โ€บ Business Logic

Race Conditions

Severity: Medium
Illustration for Race Conditions

Fire 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 lab

Opens 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.

โ† All labs