Skip to content
Field Detail
Platform PortSwigger Web Security Academy
Type Race Conditions
Difficulty Practitioner
Objective Exploit a race condition in the email change endpoint to associate [email protected] with our account, inherit admin privileges, and delete carlos

Single-Endpoint Race Conditions

I logged in as wiener:peter and tested the email change flow:

Screenshot
Screenshot
Screenshot

I duplicated the request 20 times with different addresses (teto1@exploit through teto20@exploit) and sent the group sequentially first to establish a baseline:

Screenshot

Each address received exactly the confirmation email corresponding to its own change request — normal behavior:

Screenshot

Benchmarking sequential vs parallel is how you find single-endpoint race windows. Sequential sends produce correct, correlated results; parallel sends surface anomalies. Sending the same group in parallel:

Screenshot
Screenshot

An email sent to teto16@exploit contained a confirmation link for teto20@. Recipient and confirmed address didn't match. The race condition is inside the email send operation itself — the server writes the email body (including the target email in the confirmation link) and the TO field in two separate steps. Parallel requests interleave these writes: one request's body is paired with another request's recipient. Email-based operations are disproportionately vulnerable to this because emails are often sent in a background thread after the HTTP response, extending the race window beyond the normal request lifecycle.

Weaponizing this desync with two parallel requests:

Screenshot

Repeated until the race fired — the server wrote the [email protected] payload into the body but delivered it to our inbox:

Screenshot
To confirm your email change to [email protected], click the link below

The confirmation link remains valid across attempts, so each retry doesn't reset state. Clicking the link:

Screenshot

Account email now shows [email protected]. The pending admin invite activated. Navigating to /admin and deleting carlos:

Screenshot

Lab solved

Resources