Race conditions represent a frequent vulnerability often intertwined with business logic flaws. They arise when websites handle requests concurrently without sufficient protective measures. In such scenarios, multiple threads may concurrently manipulate the same data, leading to unintended consequences due to a "collision." Exploiting this, a race condition attack orchestrates precisely timed requests to induce deliberate collisions, leveraging the ensuing unexpected behavior for malicious ends.
The time interval wherein a collision could occur is termed the "race window." This might encompass, for instance, the fraction of a second between two interactions with a database.
As with other logic flaws, the repercussions of a race condition vary significantly based on the application and the particular functionality involved.
One of the most commonly recognized race conditions occurs when you surpass a limit set by the application's business logic.
Take, for instance, an online store where you can input a promotional code during checkout to receive a one-time discount on your purchase. Here's a simplified rundown of how the application might handle this:
Should you attempt to reuse the same code later on, the initial checks conducted at the beginning of the process should prevent you from doing so.
Now, let's imagine a scenario where a user who has never used this discount code before attempts to apply it twice almost simultaneously
The application briefly enters a sub-state when processing a request, starting when the server handles the first request and ending when the database is updated to reflect the code's use. This creates a short window where users can claim the discount multiple times.
Various versions of this type of attack exist, such as:
Detecting and exploiting limit overrun race conditions is straightforward. In simple terms, you just need to:
The main challenge lies in synchronizing the requests to align at least two race windows, resulting in a collision. These windows are typically only milliseconds long and can be even shorter.
Even if you dispatch all requests simultaneously, numerous uncontrollable and unpredictable external factors influence when the server processes each request and the sequence in which they're handled.