According to Google a race condition is an undesirable situation that occurs when a device or system attempts to perform two or more operations at the same time. This type of vulnerability often goes unnoticed by automated source code analyzers as they are hard to spot.
Race conditions can be a little tricky to spot and they tend to be fairly unique to the application. Unlike sql injection, cross site scripting, and other vulnerabilities you can't just grep for vulnerable functions. Race conditions can be considered a type of logic flaws which require you to actually understand what the code is doing, source code scanners fail at detecting this type of vulnerability which means they tend to slip through the cracks.
A race condition occurs when an application tries to perform two or more actions at the same time as shown below:
In the above application we are able to withdraw money from an ATM. The ATM first checks to see if we have enough money, if we do it will allow us to withdraw the cash. What happens if we were to withdraw money from two different ATMs at the same exact time? So lets say we have $500 in our bank account. When go to withdraw $500 the application will first check to see if we have enough money, if we do it will withdraw the money and our balance would be $0. If we were to perform two withdraw actions at the same time the application would check to see if we have $500 dollars for both instances which would be true. This would allow us to withdraw $500 dollars twice because both instances passed the applications verification.
If your wondering if this is actually possible to do in real life it is! Back in 2012 ATM thieves used a race condition vulnerability to steal over $1 million dollars from Citibank using cash advance kiosks at casinos as shown in the article below:
Check out the following code I got from:
https://github.com/securelayer7/Race-conditional-vulnerable-Web-application-
function start_donating()
{
$actual_link = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
if (strpos($actual_link, 'donate') !== false)
{
}
else
{
return;
}
$fil = fopen('amount.txt', 'r');
$dat = fread($fil, filesize('amount.txt'));
if ($dat< 5000)
{
echo "
";
echo "Insufficient funds. for donating";
}
else
{
$new_money = $dat-5000;
$bull = fopen('amount.txt', 'w');
sleep(3);
fwrite($bull, $new_money);
fclose($bull);
$acc1 = fopen('account.txt', 'r');
$dat = fread($acc1, filesize('account.txt'));
$add_money =$dat."\n"."5000";
$acc = fopen('account.txt', 'w');
fwrite($acc, $add_money);
fclose($acc);
}
}
Just assume you start off with $10,000 dollars.
As you can see the application first checks to see if we have over $5,000 dollars if we do it will attempt to donate the money .
You have to ask your self what would happen if you issued 4 requests at the same time. Because the requests are executing at the same time each check should pass because we have $10,000 dollars.
Next each requests will minus $5,000 from our total which will result in negative $10,000 dollars which should be impossible.
Finally, each requests will donate $5,000 dollars for a total of $20,000 dollars. So that means we used $10,000 dollars to donate $20,000 dollars, thats a huge flaw which could allow attackers to steal money by donating more than they have.
Race conditions are nearly impossible to find using automated source code analyzers this is because logic flaws are tricky to locate as you have to understand what the code is doing. You should always be on the look for these types of flaws as they can easily slip past most developers and pentesters alike.