Single-Use Coupon Under Parallel Checkout
An e-commerce checkout exposes POST /api/cart/coupon with JSON {"code":"SAVE50"}. The coupon is advertised as one use per account. A sequential second request returns HTTP 409 "Coupon already redeemed". The server takes about 120 ms between the eligibility check and the write to the coupon_redemptions table. You have a test account with an empty cart and a valid session cookie. The WAF allows at most 10 requests per second from one IP and blocks requests with identical bodies sent more than 10 times in a minute. Burp Repeater supports sending a group of tabs in parallel, and Turbo Intruder is installed. The application negotiates HTTP/2. You need to determine whether the coupon can be applied more than once and, if so, how many times.
1. How do you confirm a race window using Burp Repeater, and what would you look for in the responses?
Read the worked answer
First establish the sequential baseline: one POST returns 200 and a second returns 409. Then open eight Repeater tabs with the identical coupon request and the same session cookie, and select Send group in parallel. With HTTP/2, Burp's single-packet attack sends the requests together so they hit the 120 ms check-then-write window. Inspect every response: a race is present if two or more return 200 and the cart JSON shows the discount applied more than once. If exactly one 200 and seven 409s appear, either the window is too small for this timing or the server uses an idempotency key or atomic update. Check response headers for an idempotency key, and compare the order totals, not just status codes. Repeat with 2, 4, and 8 tabs to see whether success scales with concurrency. Use Logger to confirm the requests were sent within the same few milliseconds.
2. The WAF permits 10 requests per second but blocks more than 10 identical bodies per minute. How do you adapt, and how do you avoid a false positive from caching?
Read the worked answer
Keep the parallel group at eight or ten requests, all sent in one burst, so you stay under the 10 per second limit. Do not repeat the same body more than once per minute; if you need a second attempt, wait and use a fresh cart or coupon state. Identical bodies are required for the race, so avoid adding random parameters that might change server-side behavior. To rule out caching, check that the coupon response has Cache-Control: no-store and that the 200 responses contain distinct server-side timestamps or cart versions. A cache would return the same response to every request, but it would not normally apply a discount. Confirm by checking the cart with a separate GET after the burst: if the total reflects multiple discounts, the effect is server-side. If all eight responses are byte-identical, treat it as a cache or proxy artifact, not a race.
3. If the race succeeds, how do you quantify impact and what fix do you recommend?
Read the worked answer
Quantify by reading the cart total after the burst and then attempting checkout. If eight 200s produce eight discount applications, record the pre-discount total, the post-discount total, and the maximum order value the coupon can cover. Test whether the same technique works across two accounts or two coupons to estimate exposure. The fix is an atomic conditional write: UPDATE coupons SET redeemed=redeemed+1 WHERE code=? AND redeemed<max_uses, and a unique constraint on (account_id, coupon_id). Reject the request if the affected row count is zero. Add an idempotency key per checkout attempt and do the eligibility check inside the same transaction. Verify with the same eight-tab parallel group: expect one 200 and seven 409s, and confirm the cart total reflects a single discount.