Race Conditions
Exploiting race conditions in concurrent operations
Quick answer
What is Race Conditions?
Race conditions happen when the app doesn't correctly handle concurrent operations. They let you duplicate actions, bypass limits, manipulate intermediate states or exploit the time window between check and use.
Severity
High
Frequency
Less common
Payloads
7
Steps
5
Severity
High
Frequency
Less common
Payloads
7
The TOCTOU pattern (Time-of-Check-Time-of-Use) is the most dangerous: the app checks a condition, but in the time between the check and the action the state changes. This is exploited by sending multiple simultaneous requests to 'win the race'.
Where to look
Discount codes
Applying the same coupon before it's marked as used. The classic race condition target.
Money transfers
Sending two simultaneous transfers with the same balance — possible double-spending.
Likes and votes
Incrementing counters without limit by sending concurrent requests.
Creation with uniqueness
Creating two resources that should be unique (e.g. same username) by sending simultaneous requests.
Payment processing
Adding items to the cart while the payment is processing — pay less than you receive.
Methodology
Identify check-then-act operations
Look for code that first checks (enough balance? valid coupon?) and then acts (transfer, apply discount).
Prepare requests
Set up 10-50 identical requests in Burp Repeater (Group Send) or Turbo Intruder.
Send simultaneously
Fire all requests at once. The goal is for them to reach the server before the first one is processed.
Verify results
Was the coupon applied 3 times? Was the transfer duplicated? Were 2 accounts created with the same email?
HTTP/2 single-packet attack
HTTP/2 lets you send multiple requests in a single TCP packet — it removes network jitter.
Real-world case
TOCTOU Race Condition with symlinks → server file read → ATO
Identify sequential operations
The server runs 3 steps: fsAccess (check it exists) → isBlocked (check it's not blocked) → createReadStream (read the file).
Each step resolves symlinks independently
Between step 1 and step 2, the symlink can change its target. 3 resolutions = 3 race opportunities.
Manipulate the symlink via Git branches
Create a repo with 2 branches: main (symlink→/etc) and second (symlink→/home). Switch rapidly between branches.
Win the race
In ~10-20 iterations the timing aligns: step 1 resolves to /home (allowed), step 3 resolves to /etc (blocked but the check already passed).
Escalate to ATO
Read database.sqlite → extract hashes. Read config → extract encryptionKey → derive JWT secret → forge an admin JWT.
Lesson: File operations that resolve symlinks in separate steps are vulnerable to TOCTOU. Git branches let you change the symlink target in a controlled way.
Payloads
Burp Group Send
Repeater → Seleccionar 20 tabs → Click derecho → Send group (parallel)
Python threading
import threading\nfor _ in range(20): threading.Thread(target=send_request).start()
curl parallel
seq 20 | xargs -P 20 -I {} curl -X POST https://target.com/api/apply-coupon -d 'code=SAVE50'Advanced payloads(account required)
Turbo Intruder — race
def queueRequests(target, wordlists):\n for i in range(50):\n engine.queue(target.req, gate='race')\n engine.openGate('race')HTTP/2 single-packet
Enviar 50 requests en un solo paquete TCP — requiere HTTP/2 + herramienta compatible
Asyncio race
import asyncio, aiohttp\nasync def race():\n async with aiohttp.ClientSession() as s:\n tasks = [s.post(url, data=payload) for _ in range(50)]\n await asyncio.gather(*tasks)
Double-spending
Enviar 2 transferencias simultáneas: {from: A, to: B, amount: 100} + {from: A, to: C, amount: 100} (saldo = 100)Exclusive content
Create your free account to access advanced payloads, scripts and bypass techniques
Create free accountTools
Turbo Intruder (Burp)
Burp extension to send requests at extreme speed with gating.
Burp → Extensions → Turbo Intruder → race.py template
race-the-web
Dedicated tool for race condition testing.
race-the-web config.toml
Tips
Coupons = target #1
Send 10 requests applying the same coupon — if it applies more than once, it's a race condition.
Look for check-then-act
Code that checks first and acts afterwards without an atomic lock is vulnerable.
HTTP/2 removes network jitter
With HTTP/2, all requests travel in the same TCP packet — perfect timing.
- hunters training
- 650
- labs from real reports
- 50
- completions
- 380
- in bounties practiced
- $200,000
hunters training
labs from real reports
completions
in bounties practiced
Practice Race Conditions with real labs
Apply these techniques in safe environments based on real bug bounty reports.