Skip to main content
  1. Research & Techical Notes/

Race conditions vulnerabilities

·2148 words·11 mins
Nguyen Hoang Thanh Phong
Author
Nguyen Hoang Thanh Phong
Senior Information Assurance student at FPT University. Focused on Web vulnerability exploitation, AWS Security Architecture, and building automated penetration tooling
Table of Contents
Web Security IAW301 - This article is part of a series.
Part 17: This Article

Question & Answer
#

1. What are Race Condition vulnerabilities, and how do they differ from other types of vulnerabilities in web applications? Explain the concept of a race condition, including how concurrent processes or threads can lead to unexpected or insecure states.
#

A race condition is a vulnerability that occurs when an application’s security decision depends on the timing or ordering of multiple operations that can run concurrently. In a secure design, a sensitive operation should check a condition and update the related state as one atomic action. In a vulnerable design, there is a small time window between the check and the update. If two or more requests enter this window at almost the same time, they may all pass the same validation check before the application records that the action has already been used.

Race conditions differ from many other web vulnerabilities because the malicious input may look completely valid. For example, SQL Injection usually depends on breaking the structure of a database query, and Cross-Site Scripting depends on injecting executable client-side code. A race condition instead abuses a flaw in the application’s workflow, state management, locking, or transaction handling. The attack is not mainly about a special payload; it is about sending legitimate requests at the right time so that the server processes them in an unsafe order.

Most web applications process many requests at the same time. This concurrency may involve multiple worker threads, asynchronous tasks, database transactions, or distributed services. If the application uses shared state, such as account balance, coupon usage, inventory quantity, password reset status, or session data, each request must update that state safely.

A race condition appears when two operations access the same shared state concurrently and at least one of them modifies it. The final result depends on timing rather than a reliable security rule. For example, the application may perform the following logic when applying a coupon:

1
2
3
4
1. Check whether the coupon has already been applied.
2. If not applied, calculate the discount.
3. Add the discount to the cart.
4. Mark the coupon as used for this cart.

If requests are processed sequentially, this logic appears safe. However, if many coupon requests arrive at nearly the same time, several requests may complete the validation step before any request updates the coupon state. They all believe the coupon is still unused, so the same discount is applied multiple times. This creates an insecure state where the cart total becomes lower than the business rule intended.

2. Describe the process of exploiting a Race Conditions vulnerability in a web application or system. What techniques can an attacker use to induce a race condition, and how can such vulnerabilities lead to security breaches or data corruption?
#

A practical methodology for exploiting a race condition begins with identifying a workflow that contains a security or business limit. Good candidates include coupon redemption, account balance updates, checkout operations, password reset flows, account registration, email changes, gift card redemption, rate limiting, file uploads, or privilege changes.

The tester first benchmarks normal behavior by sending the request sequentially. This establishes the intended control. For example, applying a coupon once should succeed, while applying it again should return a rejection message such as Coupon already applied. The tester then sends the same request many times in parallel to determine whether several requests can pass the validation before the state is updated.

Common techniques for inducing a race condition include:

  • Sending duplicate requests in parallel using Burp Repeater tab groups.
  • Using HTTP/2 multiplexing and the single-packet attack to reduce network jitter.
  • Using last-byte synchronization for HTTP/1.1 targets.
  • Using Turbo Intruder for larger or more complex request batches.
  • Repeating the attack after resetting the application state, because race windows may be small and unreliable.
  • Testing multi-step workflows where two different endpoints modify related state at the same time.

Race conditions can lead to security breaches and data integrity problems. Depending on the affected workflow, attackers may bypass rate limits, redeem a coupon or gift card multiple times, purchase products for an unintended price, withdraw or transfer money more than once, create inconsistent records, bypass authorization checks, or obtain privileges that should not be granted.

Limit overrun race conditions
#

Lab objective
#

The objective of this PortSwigger Web Security Academy lab is to exploit a limit overrun race condition in an e-commerce purchasing flow. The application provides the coupon code PROMO20, which should apply a 20% discount only once. By sending many coupon application requests in parallel, I attempted to make the application apply the same coupon multiple times and reduce the price of the Lightweight “l33t” Leather Jacket below my available store credit.

Step 1: Open the lab application
#

I opened the PortSwigger Web Security Academy lab titled Limit overrun race conditions. The home page showed an online shop and displayed the available promotion code:

1
For 20% off use code at checkout: PROMO20
Homepage

This confirmed that the lab’s attack surface was likely related to the purchasing workflow and the coupon mechanism.

Step 2: Open the target product
#

Next, I opened the product page for the Lightweight “l33t” Leather Jacket. This was the required item for solving the lab. The product price was much higher than the available store credit, so a normal purchase was not possible.

Product Page

The product page allowed the item to be added to the cart. Since the lab objective was to purchase this expensive product, I added one unit of the jacket to the cart.

Step 3: Review the cart before applying the coupon
#

After adding the jacket to the cart, I opened the cart page. The cart showed the jacket price as $1337.00, while the available store credit was only $45.89.

Payment Page

At this point, the order could not be placed because the total amount was far higher than the account balance. This confirmed that the exploit needed to reduce the total price before checkout.

Step 4: Apply the coupon once to understand the normal behavior
#

I entered the coupon code PROMO20 and clicked Apply. The application accepted the coupon and applied a single 20% discount to the cart.

Applied Coupon

After one successful coupon application, the total was still too high to purchase the jacket. This was expected because a single 20% discount was not enough. The important observation was that the coupon feature changed server-side cart state, which made it a strong candidate for race condition testing.

Step 5: Capture the coupon request in Burp Suite
#

I enabled Burp Suite Proxy and captured the coupon request in the HTTP history. The relevant request was:

1
2
3
4
5
6
POST /cart/coupon HTTP/2
Host: <lab-id>.web-security-academy.net
Cookie: session=<session-value>
Content-Type: application/x-www-form-urlencoded

csrf=<csrf-token>&coupon=PROMO20
HTTP History

The request contained two body parameters: a valid csrf token and the coupon value PROMO20. Because the request applied the discount, I sent this request to Repeater for controlled testing.

Step 6: Benchmark the normal sequential behavior
#

Before attempting the race condition, I tested the request normally. When the coupon request was sent once, the server responded with a successful result such as Coupon applied. When the same coupon was sent again after it had already been applied, the intended behavior was to reject the duplicate coupon application.

This sequential behavior indicated that the application did implement a limit. However, it did not prove that the limit was enforced atomically. The next step was to test whether the limit could be overrun by concurrent requests.

Step 7: Create a Repeater group with many identical coupon requests
#

In Burp Repeater, I created a group of repeated POST /cart/coupon requests. Each tab used the same session cookie, CSRF token, and coupon value.

Make Group of Request

The purpose of the group was to send many identical coupon application requests as close together as possible. If the application checked the coupon state and updated the cart state in separate non-atomic operations, multiple requests could pass the coupon not yet applied check before the server recorded the coupon usage.

Step 8: Send the grouped requests in parallel
#

After preparing the Repeater group, I used the group send option and selected the parallel sending mode.

Send Parallel Group of Request

This technique attempted to trigger the race window by making the server process many coupon requests simultaneously. In this lab, I selected Burp Repeater’s parallel group sending option, specifically the single-packet attack mode. This helps minimize network jitter and makes the grouped requests reach the server at almost the same time.

Step 9: Observe multiple successful coupon applications
#

After sending the group in parallel, several requests returned a successful coupon response. This suggested that multiple requests entered the vulnerable window before the application updated the server-side cart state.

Parallel Attack

The successful responses were important because a secure implementation should allow only one coupon application per cart. Multiple successful responses showed that the business rule was not enforced atomically.

Step 10: Refresh the cart and inspect the discounted total
#

I refreshed the cart page to check whether the repeated coupon requests changed the cart total. The cart showed that the same coupon had been applied many times, reducing the total price significantly.

Test 1

On the first attempt, the total was reduced close to the available store credit but was still slightly too high. This showed that the race condition was working, but I needed a stronger or repeated attempt to bring the total below the store credit.

Step 11: Repeat the attack until the total is below the store credit
#

I removed the applied coupon from the cart when necessary and repeated the parallel request group. After another successful attempt, the repeated discount reduced the total to $15.40, which was below the available store credit of $45.89.

Test 2

This confirmed that the limit overrun race condition was exploitable. The application intended the coupon to be used once, but concurrent requests caused the same discount to be applied multiple times.

Step 12: Place the order and solve the lab
#

Finally, I clicked Place order while the cart total was below the available store credit. The order was accepted, and the lab status changed to Solved.

Success

The final confirmation showed that the expensive jacket was purchased for an unintended price. This completed the lab.

Vulnerability explanation
#

The root cause of the vulnerability is a non-atomic check-and-update operation in the coupon application workflow. The application checks whether the coupon has already been applied, but it does not lock the cart state or perform the check and update inside a safe transaction. As a result, multiple parallel requests can all pass the validation condition before the application records the coupon as used.

This type of issue is called a limit overrun race condition. The business rule says that the coupon should only be applied once, but concurrent execution allows the limit to be exceeded. The exploit does not require bypassing input validation, changing the coupon value, or modifying the price directly. It abuses timing and concurrency to make legitimate requests produce an unintended final state.

Security impact
#

The demonstrated impact is unauthorized price reduction. In a real e-commerce application, this could cause direct financial loss because attackers may purchase products for prices below the intended amount. Similar race conditions could also affect gift cards, refund systems, loyalty points, inventory limits, rate limits, account balance updates, or other business-critical workflows.

Potential impacts include:

  • Applying one-time coupons or discounts multiple times.
  • Redeeming gift cards or store credit more than once.
  • Purchasing products for an unintended price.
  • Bypassing rate limits or usage limits.
  • Creating inconsistent cart, payment, or inventory records.
  • Causing financial loss and data integrity issues.

Remediation recommendations
#

To prevent this vulnerability, the application should make the coupon validation and coupon application logic atomic. The server must ensure that only one request can apply a coupon to a cart at a time.

Recommended defenses include:

  • Wrap the coupon check and update in a single database transaction.
  • Use row-level locking or equivalent server-side locking for cart and coupon state.
  • Enforce a unique database constraint that prevents the same coupon from being applied to the same cart more than once.
  • Avoid relying only on application-layer checks without database-level protection.
  • Recalculate the cart total on the server immediately before checkout.
  • Validate that the final order total is consistent with all coupon and account-balance rules.
  • Make sensitive operations idempotent where possible.
  • Add monitoring for repeated coupon applications, abnormal discounts, and unusually large request bursts.

Conclusion
#

This lab demonstrated a limit overrun race condition in an e-commerce coupon workflow. Under normal sequential testing, the coupon appeared to be limited to one use. However, by capturing the POST /cart/coupon request and sending many copies of it in parallel through Burp Repeater, I caused the server to apply the same coupon multiple times. This reduced the price of the Lightweight “l33t” Leather Jacket below the available store credit, allowing the order to be placed successfully and solving the lab.

Web Security IAW301 - This article is part of a series.
Part 17: This Article