Race Conditions
Anything that reads state, decides, then writes state has a window. Hit it with two requests before the write lands.
Where to look
- Redeem coupon / gift card / referral credit
- Withdraw, transfer, refund
- Follow, like, vote, rate (one-per-user limits)
- Accept invite, join team (seat limits)
- Password reset token consumption
- 2FA / OTP validation (bypasses the attempt counter)
- Email change confirmation
- Anti-bruteforce counters
- Free-trial provisioning
Single-packet attack
Puts 20-30 requests in one TCP packet so network jitter can’t spread them. HTTP/2 only.
Burp Repeater > select tabs > Send group in parallel (single-packet attack)Turbo Intruder:
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=1,
engine=Engine.BURP2)
for i in range(20):
engine.queue(target.req, gate='race1')
engine.openGate('race1')Last-byte sync (HTTP/1.1)
No HTTP/2? Open N connections, send everything but the final byte, wait, then release the last bytes together.
Burp Repeater > Send group in parallel (falls back to last-byte sync on HTTP/1.1)Warm the connection first
The first request on a connection is slower. Send a junk request before the group so TLS and the server-side pool are already hot.
Signals
- The same nonce / token / code accepted twice
- Balance goes negative
- Two rows with the same “unique” value
- Limit of 1 becomes 2 — that is already the bug, do not chase 20
- A 500 that only appears under parallel load
Multi-endpoint races
Two different endpoints on the same state. Classic: add item to cart while the payment is being captured.
POST /cart/add } sent together
POST /checkout/pay }Single-endpoint, different values
Two email-change confirmations submitted at once can leave the account bound to one address and the confirmation to another.
Partial construction
Send a request the moment an object exists but before it is initialised — a user row created before its permissions row is written.
Articles
| URL | Description |
|---|---|
| https://portswigger.net/research/smashing-the-state-machine | The single-packet attack |
| https://portswigger.net/web-security/race-conditions | Labs |
| https://github.com/PortSwigger/turbo-intruder | Turbo Intruder |