Race Conditions
Race condition exploitation: limit overrun (coupon/vote/balance abuse), time-of-check to time-of-use (TOCTOU), single-packet attack technique, Turbo Intruder setup for parallel requests, and Burp Repeater parallel groups.
What are Race Conditions
A race condition occurs when the outcome depends on the timing of multiple operations. In web apps, if a server checks a condition then acts on it in two separate steps — and an attacker sends many requests simultaneously — multiple requests can pass the check before any of them triggers the action. Classic result: spending a one-time coupon multiple times, withdrawing more than a balance, voting multiple times.
Types of Race Conditions
| Type | Description | Example |
|---|---|---|
| Limit overrun | Bypass a one-time or max-count restriction | Use discount code 10 times |
| TOCTOU | State changes between check and use | File validated, then replaced before processing |
| Multi-step sequence flaw | Two actions must happen in order; race skips the check | Confirm email before buy; skip confirm |
| Partial construction | Object partially initialised and usable during setup | Register flow — user exists but has no role yet |
Detection
Look for state-changing endpoints with limits
In Burp Proxy history, identify:
- Single-use tokens / codes (vouchers, reset tokens, email verify)
- Rate-limited actions (login, vote, like, purchase)
- Balance-dependent actions (transfer, withdraw, redeem)
- Sequenced multi-step flows (verify → approve → action)
Test with two parallel requests
In Burp Repeater:
- Send the target request once to confirm it works.
- Add it to a Repeater group (right-click → Add to group).
- Duplicate the tab 10–20 times.
- Select Send group in parallel (the dropdown next to Send).
If you get multiple 200 OK / success responses where only one should succeed → vulnerable.
Single-Packet Attack (HTTP/2)
The most reliable technique. HTTP/2 multiplexes multiple requests over one TCP connection. By sending them in a single packet, they arrive at the server simultaneously — eliminating network jitter.
In Burp Repeater:
- Switch connection to HTTP/2 (Repeater menu).
- Group your parallel requests.
- Send group in parallel (single-packet attack) — this sends all requests in one HTTP/2 frame.
HTTP/1.1 equivalent (last-byte sync): hold back the last byte of each request, then send all final bytes simultaneously using Turbo Intruder.
Turbo Intruder — Parallel Attack Setup
Install Turbo Intruder from BApp Store.
Send the target request to Turbo Intruder (right-click → Extensions → Turbo Intruder → Send to Turbo Intruder).
Use the race_single_packet_attack.py template:
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=1,
engine=Engine.BURP2)
# Queue 20 identical requests
for i in range(20):
engine.queue(target.req)
def handleResponse(req, interesting):
table.add(req)
Click Attack. All 20 requests are sent in one HTTP/2 packet.
Exploit: Limit Overrun (Gift Card / Coupon)
Classic pattern — the app checks: “Is this coupon valid and unused?” then marks it used in a second DB write. Race the check:
- Identify the redemption request in Proxy.
- Send to Repeater, duplicate 15-20 times, group them.
- Send group in parallel (single-packet attack).
- Check how many responses show a success / discount applied.
If more than one succeeds → the coupon was redeemed multiple times.
Exploit: Balance / Withdrawal Limit Overrun
POST /transfer HTTP/1.1
Host: TARGET
Cookie: session=YOUR_SESSION
Content-Type: application/json
{"amount": 1000, "to": "attacker_account"}
Race 10 identical transfer requests simultaneously. If the balance check and debit are not atomic, multiple transfers can pass the balance check before any of them deducts.
Exploit: TOCTOU — File Upload Validation
App pattern:
- Upload a file → validate (check for PHP in it) → if clean, move to final location.
- Race condition: upload PHP webshell and access it in the brief window between upload and validation.
# Terminal 1: upload the shell repeatedly
while true; do
curl -s -X POST https://TARGET/upload \
-F "file=@shell.php" \
-b "session=SESSION"
done &
# Terminal 2: access it in the temp location
while true; do
curl -s https://TARGET/uploads/tmp/shell.php?cmd=id
done
Exploit: Multi-Endpoint Race (Partial Construction)
Some objects are partially valid between creation and the final write. Example: a user is created in DB with a null role, then the role is set in a second query. Race a privileged action in that window:
- Trigger account creation.
- Simultaneously send requests that require a role check.
- If one of them lands between the two DB writes → executes with undefined/default/admin role.
Exploit: Email Verification Bypass
If the flow is: register → verify email → gain access, and the verification token is checked but the account isn’t locked until after:
- Register with your email.
- Get the verification token.
- Race: submit the token AND simultaneously submit a token for a different action (e.g. change email to victim@target.com).
If the token check and the email write are not atomic → you verify a different email than the one the token was issued for.
Burp Suite workflow
- Proxy — identify limit-enforced or single-use endpoints.
- Repeater — group identical requests, use Send group in parallel (single-packet attack) over HTTP/2.
- Turbo Intruder — for larger-scale attacks (50–500 concurrent); use
race_single_packet_attack.py. - Inspector — watch response times and lengths to detect winner/loser patterns.
- Vary the number of concurrent requests — start with 20, increase if the race window is narrow.