[In this lab](https://portswigger.net/web-security/race-conditions/lab-race-conditions-limit-overrun), the app has a logic flaw in its discount application mechanism. It intends to **limit a discount coupon to a single use per user/cart**, but due to a race condition, multiple concurrent requests **apply the discount multiple times before the server updates the “already used” flag.** This is a _time-of-check to time-of-use (TOCTOU)_ issue — a classic example of unsafe concurrent operations on shared state (in this case, your server-side cart). --- ##### Attack Path Summary Here’s how the exploit played out: |Step|Action| |---|---| |1️⃣|Logged in as `wiener:peter` and added a cheap item to cart| |2️⃣|Applied the coupon normally — saw that it works once| |3️⃣|Noticed coupon can't be applied twice — restriction is server-side| |4️⃣|Sent **20 parallel POST requests** to apply the coupon using Burp tab group| |5️⃣|Observed **multiple successful responses**, discount applied multiple times| |6️⃣|Replaced cart item with **Lightweight L33t Leather Jacket**| |7️⃣|Repeated race attack, reduced total below credit| |✅|Purchased jacket for cheap, lab solved| --- ##### Root Cause Breakdown |Component|Behavior| |---|---| |`/cart/coupon`|Accepts coupon if not already applied| |Session-based state|Cart contents and applied coupon tracked in server session| |Vulnerability|The backend checks “has this user used the code?” but doesn’t lock the session during concurrent requests| |Result|Multiple requests sneak through the check before the flag is set, each applying a new discount| ##### Step 1: Log In 1. Click “**Access the Lab**” 2. Go to **Login** page 3. Enter: - Username: `wiener` - Password: `peter` 4. You should now be in your account. --- ##### Step 2: Add a Cheap Item to Your Cart 1. Go to the **Shop** page 2. Find the **cheapest item** (e.g., a sticker or socks) 3. Click **Add to Cart** --- ##### Step 3: Apply the Discount Code Normally 1. Go to the **Cart** 2. Scroll down and find the **Apply Coupon** input box 3. Type in: `SIGNUP30` 4. Click **Apply** 5. You should see a message like: “Coupon applied successfully – 20% off” ✅ This confirms the discount works. ❌ Try applying again — it should now say “Coupon already applied” --- ##### Step 4: Send the Discount Request in Burp Repeater ### A. Open Burp → Proxy → HTTP History 1. Find the request to `/cart/coupon` 2. Right-click → **Send to Repeater** ### B. Remove the Coupon First Go back to the cart and **remove the coupon** (there should be a “Remove” or “x” button near it). This gives you a clean slate. --- ##### Step 5: Create a Tab Group in Burp Repeater 1. In Repeater, right-click the coupon request tab 2. Choose **“Add to new tab group”** 3. Now right-click the tab in the group → **“Duplicate tab”** 4. Repeat this 19 times → You should now have **20 tabs in the group** --- ##### Step 6: Send All Requests in Parallel 1. Right-click on the **tab group name** 2. Select: **Send group → In parallel** 3. Burp will fire all 20 requests at once ![[CleanShot 2025-04-15 at 17.34.37.png]] --- ##### Step 7: Check the Responses - Some will say: ✅ `Coupon applied successfully` - Others will say: ❌ `Coupon already applied` If **2 or more requests say “applied successfully”**, the discount stacked! --- ##### Step 8: Refresh Cart & Check the Price - Reload the cart in your browser - Check if the jacket price is **significantly reduced** - You may see it drop **multiple times by 20%** Example: - Original: $1337 - After stacking: $1337 → $1069.60 → $855.68 → $684.54 → ... ![[CleanShot 2025-04-15 at 17.36.37.png]] --- ##### Step 9: Buy the Jacket If the final price is **less than your store credit**, just hit **Purchase**. ##### Recap: Why This Works - Server checks “has this user used the coupon?” - But it doesn’t lock the cart/session during the check - 20 parallel requests all sneak through the check before any of them updates the session - This stacks the discount over and over