Race Condition Vulnerability
What is Race Condition Vulnerability ?
A race condition is a flaw that produces an unexpected result when the timing of actions impact other actions. An example may be seen on a multithreaded application where actions are being performed on the same data. There is a possibility that a race condition vulnerability exists where an attacker can trick the system into carrying out unauthorized actions in addition to its normal processes.
For example, before allowing someone to log in, a security system first receives their username and password and then checks it against a database before allowing access. Attackers can exploit this fact by interfering with processes to access secure areas and content in what’s known as a race condition attack.
How the race condition vulnerabilities can be exploited?
There are two main ways this attack is carried out:
- Interference by an untrusted process — The attacker inserts a piece of code in between the steps of a secure process.
- Interference by a trusted process — The attacker exploits two different processes that share some state in common.
Example 1:
Client-side actions-
In most cases, multithreaded software is used as a client to check/exploit the race condition, e.g., Burp Suite and its Intruder tool. They put one HTTP request on repeat, create multiple threads, and start flooding. This is a working way if the server allows the use of multiple threads to its resource, and as the articles above say: if it didn’t work, try again. But the fact is that in some cases this may not be effective. Especially if we think back to how such applications access the server.
Server-side actions-
Each thread establishes a TCP connection, sends data, waits for a response, closes the connection, opens it again, sends data, and so on. At first glance, all data is sent at the same time, but HTTP requests themselves may not arrive synchronously due to the nature of the transport layer, the need to establish a secure connection (HTTPS) and resolve DNS (not in the case of Burp), as well as due to many layers of abstraction that data pass through before being sent to a network device. When it comes to milliseconds, this can play a key role.
Example 2:
Using HTTP Pipelining
Client-side actions-
For example, run nc google.com 80 command and insert the following lines there
GET / HTTP/1.1
Host: google.com
GET / HTTP/1.1
Host: google.com
GET / HTTP/1.1
Host: google.com
Thus, within one connection, three HTTP requests will be sent, and you will receive three HTTP responses. This feature can be used to minimize the time between requests.
Server-side actions-
The web server receives requests sequentially (this is the key point), and processes the responses in the same order. This peculiarity can be used to attack in several steps (when it is necessary to sequentially perform two actions in the minimum amount of time) or, for example, to slow down the server in the first request to increase the success of the attack.
Example 2:
Read-modify-write
This kind of race condition happens when two processes read a value in a program and write back a new value. It often causes a software bug. Like the example above, the expectation is that the two processes will happen sequentially — the first process produces its value and then the second process reads that value and returns a different one.
For example, if checks against a checking account are processed sequentially, the system will make sure there are enough funds in the account to process check A first and then look again to see if there are enough funds to process check B after processing check A. However, if the two checks are processed at the same time, the system may read the same account balance value for both processes and give an incorrect account balance value, causing the account to be overdrawn.
Impact of a Race Condition Attack
As with most security breaches, a successful race condition attack can grant attackers access to secured areas of an application. In the example above, once the attacker replaces the database update with their own set of data, they will be able to log in as an administrator. Other possibilities include manipulating API calls, tricking a central server into executing the same action multiple times despite it not being valid after the first time.
How to prevent systems from race condition attacks?
Race condition vulnerabilities are created when the result of computation depends upon the order of execution of parallel processes. Protecting against exploitation requires removing this dependency. Common methods include the use of mutexes and atomic operations to prevent race conditions within the code and the use of random temporary filenames to minimize the probability that an external process could predict and modify files containing important data. These protections need to be carefully designed to remove the possibility of deadlock.
Following attack prevention techniques are used:
1. Locks:
The operation blocks the access to the locked object in the DBMS until it is unlocked. Others stand and wait on the sidelines. It is necessary to work with locks correctly, not to lock anything extra.
2. Isolations:
Serializable transactions ensure strictly sequential execution. This, however, can impact performance.
3. Mutual exclusions:
We use a tool like etcd to create an entry with a key at each function call. If it is not possible to create an entry, then it already exists and the request is interrupted. At the end of request processing, the entry is deleted.
4. Session Capabilities in Race Condition:
The session itself may prevent exploitation of the race condition. For example, in PHP, after session_start(), a session file is locked, and its unlocking occurs only at the end of the script (if there was no call of session_write_close). If another script that uses the session is called at this moment, it will wait.
References
https://portswigger.net/daily-swig/google-recaptcha-outfoxed-by-turbo-intruder
https://portswigger.net/research/cracking-recaptcha-turbo-intruder-style