| Field | Detail |
|---|---|
| Platform | PortSwigger Web Security Academy |
| Type | Race Conditions |
| Difficulty | Practitioner |
| Objective | Exploit a race condition across the cart and checkout endpoints to purchase the Lightweight L33t Leather Jacket with insufficient funds |
Multi-Endpoint Race Conditions¶
I logged in as wiener:peter — $100 store credit, jacket costs more. Purchasing it directly returned INSUFFICIENT_FUNDS. I bought a gift card first to understand the purchase flow:
I captured both requests in Repeater and measured their processing times in sequence:
POST /cart→ ~477msPOST /cart/checkout→ ~200ms
Benchmarking before attacking matters: the endpoints have different processing times, which means they don't naturally align for a race window. checkout completes in 200ms while cart add takes 477ms — pure parallel timing may not work without deliberately creating processing overlap on one side.
The checkout endpoint reads cart contents, validates payment, then confirms the order. The race window is between steps 2 and 3 — if the jacket gets added to the cart after payment validation but before order confirmation, it may be included in the confirmed order without being part of the validation.
A simple two-request parallel attempt (add jacket + checkout) doesn't work reliably. The working setup uses three requests with a coupon applied to the initial cart:
POST /cart—productId=1(jacket)POST /cart/checkoutPOST /cart—productId=1(jacket, second add)
The coupon isn't incidental — it extends the validation phase on the checkout side, giving the cart-add requests more time to land during the race window. Sending the cart-add twice (before and after checkout) is a timing hedge: if the first fires too early or too late, the second has another chance to collide with the confirmation phase.
The three requests arrived simultaneously. The checkout processed the initial cart and validated payment, but while finalizing, one of the jacket adds landed during the window — the order confirmation included the jacket at the validated price.
Lab solved