Introduction
In this blog, we explore a race condition vulnerability using a hands-on PortSwigger lab. Race conditions occur when a systemโs behavior depends on the timing or sequence of uncontrollable events, such as simultaneous requests. If not handled properly, this can lead to serious security issues like bypassing controls or performing unauthorized actions. Through this lab, weโll demonstrate how to exploit such a vulnerability by sending concurrent requests, ultimately gaining an advantage over the applicationโs intended logic.
Understanding The Race Condition
Race conditions are a type of business logic vulnerability that occur when a web application handles multiple operations on the same data at nearly the same time โ without proper synchronization. When two or more actions are processed in parallel, and the app doesnโt manage them correctly, this can create unintended behavior. An attacker can exploit this by sending multiple rapid requests to force a collision, gaining advantages the system wasnโt meant to allow.
A common example is using a discount code or gift card. Imagine an online store that checks if youโve used a promo code, applies a discount, and then marks it as used. If an attacker sends two requests at the same time, they might sneak both through before the database updates. This tiny moment โ between the check and the update โ is known as the race window. If timed correctly, the attacker could use the same code multiple times.
These attacks fall under a broader flaw known as TOCTOU (Time-Of-Check to Time-Of-Use), where a check is done first but becomes outdated before the actual use happens.
There are many ways this can be abused, such as:
- Reusing a one-time gift card
- Rating a product multiple times to skew reviews
- Withdrawing more funds than available
- Reusing CAPTCHA answers
- Bypassing brute-force protection
Detecting this type of flaw typically involves finding endpoints that are rate-limited or meant for one-time use โ then hammering them with multiple requests to see if the limit can be bypassed.
Timing is critical. Even milliseconds can make or break the attack. That’s why tools like Burp Suite Repeater have introduced advanced features for race condition testing. The latest versions offer powerful methods to send parallel requests with high precision, even adjusting their behavior depending on the HTTP version the server supports:
- For HTTP/1, it uses the classic last-byte synchronization.
- For HTTP/2, it uses the single-packet attack โ a cutting-edge method demonstrated by PortSwigger at Black Hat USA 2023.
These techniques help minimize both network delays (jitter) and internal server delays, boosting your chances of hitting the race window. While sometimes two requests are enough to trigger the flaw, sending 20โ30 in one go can drastically improve reliability during testing.
In this blog, weโll use these concepts to walk through a practical lab that simulates a real-world race condition vulnerability โ giving you hands-on experience with the tools and mindset needed to exploit and understand this class of bugs.
Challenges
To solve the lab, successfully purchase a Lightweight L33t Leather Jacket.
You can log in to your account with the following credentials: wiener:peter
.
Walkthrough
Step 1: We logged in using the default credentials wiener:peter
. After a successful login, we noticed that the account had a $50 credit balance.
Step 2: We were challenged to purchase the Leet Leather Jacket, which costs $1337, but our account only had $50 in credit.
Step 3: We added the jacket to the cart and attempted to purchase it despite having only $50 in credit.
Step 4: We applied the coupon code PROMO20
, which was clearly visible on the page, and intercepted the coupon application request using Burp Suite.
Step 5: The screenshot below shows the intercepted coupon request.
Step 6: When we attempted to apply the coupon again, the system rejected it and displayed an error, preventing multiple uses of the same discount code.
Step 7: We sent the coupon request multiple times to Burp Repeater, then launched all requests simultaneously to exploit the race condition vulnerability.
Step 8: Since Burp Suite requires it, we created a new tab and selected all the Repeater requests before sending them simultaneously.
Step 9: Next, we chose to send the requests as a parallel group using the single-packet technique and clicked the send button.
Step 10: We refreshed the page but initially saw no change; the result remained the same as before.
Step 11: We increased the number of requests and prepared to send them in parallel again, but first, we removed the previously applied coupon.
Step 12: After refreshing the page this time, we noticed the coupon discount had increased to $1321, leaving us with only $15 to pay. Since we started with $50 in credit, we could now easily afford the Leet Leather Jacket. So, we proceeded to complete the purchase.
Step 13: As soon as we completed the purchase of the jacket, the lab was successfully solved.