Labs Covered
This write-up focuses on the following PRACTITIONER-level labs from the PortSwigger Web Security Academy related to Race Conditions:
2 Bypassing rate limits via race conditions
This lab shows how concurrent requests can overwhelm rate-limiting mechanisms, allowing attackers to bypass restrictions on the number of allowed requests.
3 Multi-endpoint race conditions
This lab demonstrates how using multiple endpoints that modify shared resources simultaneously can lead to race conditions and inconsistent application states.
4 Single-endpoint race conditions
This lab shows how a single endpoint, if accessed concurrently, can produce unintended behavior due to unsynchronized processing of shared resources.
5 Exploiting time-sensitive vulnerabilities
This lab demonstrates how attackers can exploit timing windows in processes dependent on time-sensitive operations to bypass restrictions or create inconsistent states.
LAB 2 - Bypassing rate limits via race conditions
Lab Description
123123
abc123
football
monkey
letmein
shadow
master
666666
qwertyuiop
123321
mustang
123456
password
12345678
qwerty
123456789
12345
1234
111111
1234567
dragon
1234567890
michael
x654321
superman
1qaz2wsx
baseball
7777777
121212
000000
Overview:
Detecting and Exploiting Limit Overrun Race Conditions with Turbo Intruder
In addition to Burp Repeater’s native support for parallel execution, the Turbo Intruder extension has also been enhanced to support single-packet attacks. You can download the latest version of Turbo Intruder from the BApp Store.
Why Use Turbo Intruder?
Turbo Intruder is ideal for more complex race condition exploits, such as:
- Multi-stage or retry-dependent attacks
- Staggered or precisely timed requests
- High-volume request flooding
- Full control via Python scripting
Requirements:
- Target must support HTTP/2 — single-packet attacks are not compatible with HTTP/1.
- Use:
engine = Engine.BURP2concurrentConnections = 1
Method: Single-Packet Attack in Turbo Intruder
You can queue multiple requests into a named gate, then release them all simultaneously to hit the race window with high accuracy.
Example Script:
def queueRequests(target, wordlists):
engine = RequestEngine(
endpoint=target.endpoint,
concurrentConnections=1,
engine=Engine.BURP2
)
# Queue 20 requests in gate '1'
for i in range(20):
engine.queue(target.req, gate='1')
# Open gate '1' to send all requests at once
engine.openGate('1')
Solution
Lab Solution
There are two methods to solve the lab.
Method 1: Through Burp Intruder
-
If we input three invalid attempts, the account will lock out for 1 minute.
-
Log in with the username “wiener” and intercept the request in Burp.
-
Send the request to Intruder.
-
Change the username to “carlos” (the account whose password we want to obtain) and set the payload position in the password field.
-
Configure the resource pool to send 30 requests concurrently.
-
Start the attack in Intruder. A 302 response indicates a successful race condition, and the password is found.
-
Log in with the obtained password for “carlos.”
-
Go to the admin panel, delete the “carlos” account, and the lab is solved.
Method 2: Through Turbo Intruder
-
Follow the same initial steps as the first method, but send the request from the history to Repeater.
-
Send the request to Turbo Intruder.
-
Select the “Single Packet Attack” option.
-
Paste the following password list script into the console log to retrieve the password from the list:
var passwordList = `1231
abc123
football
monkey
letmein
shadow
master
666666
qwertyuiop
123321
mustang
123456
password
12345678
qwerty
123456789
12345
1234
111111
1234567
dragon
1234567890
michael
x654321
superman
1qaz2wsx
baseball
7777777
121212
000000`.split('\n')
-
The password list is now in list form.
-
Modify the script in Turbo Intruder, where
%srepresents the parameter to fuzz (the password). -
Click “Attack.”
-
A 302 response indicates the password was successfully obtained.
-
Log in with the obtained password for “carlos.”
-
Delete the “carlos” account from the admin panel, and the lab is solved.
LAB 3 - Multi-endpoint race conditions
Lab Description
Overview
Hidden Multi-Step Sequences
Hidden multi-step sequences in HTTP requests can lead to interactions with the same data, potentially exposing time-sensitive logic flaws in multi-step workflows. These vulnerabilities can be exploited through race condition attacks, extending beyond simple limit overruns. For instance, flawed multi-factor authentication (MFA) workflows may allow an attacker to complete the first login step with known credentials and then bypass MFA entirely by navigating directly to the application via forced browsing.
The following pseudo-code illustrates a website’s vulnerability to a race condition variation of this attack:
Methodology
To detect and exploit hidden multi-step sequences, follow this methodology:
- Predict Potential Collisions
Testing every endpoint is impractical. After mapping the target site, narrow down the endpoints to test by asking:- Is this endpoint security-critical? Many endpoints do not interact with critical functionality and can be skipped.
-
Is there collision potential? Successful collisions typically involve two or more requests operating on the same record. For example, consider variations of a password reset implementation.
-
Recognize Clues in Endpoint Behavior
Use Burp Repeater to benchmark endpoint behavior under normal conditions. Group requests and send them sequentially or in parallel to minimize network jitter. Look for deviations in responses or second-order effects, treating anomalies as potential indicators of vulnerabilities. - Prove the Concept
Understand the observed effects, eliminate unnecessary requests, and ensure replicability. Advanced race conditions may reveal unique structural weaknesses rather than isolated vulnerabilities.
Challenges in Multi-Endpoint Race Conditions
Aligning race windows in multi-endpoint race conditions is complex due to network architecture delays and endpoint-specific processing variations. Factors like connection establishment and differences in endpoint processing times contribute to synchronization challenges. To mitigate this:
- Connection Warming: Send inconsequential requests (e.g., a GET request to the homepage) to “warm up” the connection, helping distinguish backend connection delays from endpoint-specific factors.
- In Burp Repeater, use the “Send group in sequence (single connection)” option, starting with a homepage GET request in the tab group, to observe and manage processing times effectively.
This approach enhances the accuracy of testing for race condition vulnerabilities in multi-step sequences.
Solution
Lab Solution
-
Log in with the provided account.
-
Purchase a gift card.
-
After buying gift card we will get the coupoun.
-
You can see in blue color we have got a code after buying gift card
- In HTTP history, observe three requests:
- GET /cart: Retrieves information about items in the cart.
- POST /cart: Adds items to the cart.
-
POST /cart/checkout: Processes the transaction for items in the cart.
- In Burp Repeater, test the GET /cart request with and without the session cookie:
- Without the session cookie, only an empty cart is accessible.
- This indicates:
- The cart state is stored server-side in the session.
- Cart operations are tied to the session ID or associated user ID.
-
This suggests potential for a collision.
-
Using the session, the GET /cart request shows the cart’s contents.
- Create a group with two requests:
- POST /cart
-
POST /cart/checkout
9 . Obtain the product ID of the Lightweight L33t Leather Jacket (product ID: 1).
10 In Repeater, modify the POST /cart request to set the productId parameter to 1 (Leather Jacket).
-
Send the grouped requests in parallel.
-
To address the issue, you should ensure that the gift card is in the cart before executing the request in parallel. If the leather jacket is not purchased but the gift card is, you should repeat the process by placing only gift cart in the cart again. During the parallel execution of requests, only the gift card will be present in the cart initially. This setup is crucial because the server assumes there’s a gift card in the cart due to parallel requests. However, due to the race condition, both the gift card and the leather jacket will end up being purchased.
-
When the race condition is successfully exploited, the Leather Jacket is purchased, and the lab is solved.
LAB 4 - Single-endpoint race conditions
Lab Description
Overview
Abusing Rate or Resource Limits
When connection warming is ineffective for aligning multi-endpoint race windows, alternative methods can be used. With Turbo Intruder, introducing a short client-side delay is one option, but this requires splitting attack requests across multiple TCP packets, reducing reliability on high-jitter targets. A more effective approach is to abuse web server rate or resource limits by sending numerous dummy requests to trigger these security features.
Exploiting Password Reset Collisions
In this scenario, sending two parallel password reset requests from the same session, but with different usernames, can cause a collision. For example:
- Send one request for the attacker’s username.
- Send another for the victim’s username simultaneously.
Outcome
When all operations are complete, the session state may be:
session['reset-user'] = victimsession['reset-token'] = 1234
This results in the session containing the victim’s user ID, but the valid reset token is sent to the attacker, enabling potential unauthorized access.
Solution
Lab Solution
-
Log in with the provided credentials.
-
Change the email address to
carlos@exploit...to understand how the email change process works. -
An email is sent with a “Click here to confirm” link to change the email to
carlos@exploit.... -
Clicking the link updates the email to
carlos@exploit.... -
Go to the HTTP history and send the email change request to Burp Repeater.
-
In Repeater, create two tabs with different email addresses:
- Tab 1: Email set to
king@exploit... -
Tab 2: Email set to
queen@exploit...Queen email
- Tab 1: Email set to
7 . Group both requests to Group1
8 . Configure them to be sent in parallel.
9 . Sending the group in parallel triggers a race condition on the server, causing the email to change to queen@exploit....
10 . An email is sent with a “Click here to confirm” link to update the email to queen@exploit....
11 . Clicking the link changes the email to queen@exploit..., achieving the race condition as the email was intended to change to king@exploit... but is set to queen@exploit....
-
Repeat the process to change the email to an address with admin access, such as
carlos@ginandjuice.shop.-
Change the email to
carlos@ginandjuice.shopand send the requests in parallel, using another email likeking@exploit....
-
-
Send the requests multiple times and refresh the browser, which will prompt a “Click here to confirm” link to change the email to
carlos@ginandjuice.shop. -
Clicking the link updates the email to
carlos@ginandjuice.shop, granting admin privileges. -
Verify that the email has been successfully updated.
-
Delete the
carlosaccount, and the lab is solved.
LAB 5 - Exploiting time-sensitive vulnerabilities
Lab Description
Overview
Time-sensitive attacks
Sometimes you may not find race conditions, but the techniques for delivering requests with precise timing can still reveal the presence of other vulnerabilities. One such example is when high-resolution timestamps are used instead of cryptographically secure random strings to generate security tokens. Consider a password reset token that is only randomized using a timestamp. In this case, it might be possible to trigger two password resets for two different users, which both use the same token. All you need to do is time the requests so that they generate the same timestamp.
Solution
Lab Solution
-
Click on “Forgot Password,” which prompts for a username or email.
-
Enter the username, sending a reset token to the
wieneremail. -
Verify that the reset token is sent to the email.
-
In the email server, locate the reset token. Clicking the link directs to the password reset page.
-
The reset page prompts for a new password and confirmation.
- In HTTP history, identify two requests:
- GET /forgot-password: Navigates to the forgot-password section.
-
POST /forgot-password: Submits the username and CSRF token to send the password reset link.
- Send the POST /forgot-password request to Burp Repeater twice, naming them
POSTandPOST1(both identical).-
Group the
POSTandPOST1requests to send them in parallel.
Post request
Post1 request
-
-
Send a GET /forgot-password request with the session cookie.
-
Send a GET /forgot-password request without the session cookie to obtain a new session cookie and CSRF token. These will be used for the race condition.
- Send both POST /forgot-password requests in parallel. Initially, a significant difference in response times indicates sequential execution due to identical CSRF tokens and cookies, preventing a successful race condition.
-
Replace the CSRF token and cookie in the
POSTrequest with the new values obtained from the GET /forgot-password request without the cookie. -
Resend both POST /forgot-password requests in parallel. Minimal difference in response times (similar for
POSTandPOST1) indicates potential for a race condition.
post1
-
Modify the
POSTrequest to change the username tocarlosto obtaincarlos’s reset token via the race condition. The same token becomes valid for bothwienerandcarlosdue to parallel requests. -
Check the email server for the reset token message and copy it.
-
Attempt to use the token with the username
carlos. If an “Invalid token” error appears, resend the parallel requests until successful. -
After several attempts, obtain a valid reset password token for
carlosand use it to change the password.
-
Log in with the new
carlospassword. -
Delete the
carlosaccount, and the lab is solved.