Race condition to financial fraud on Payment App
Summary:
This vulnerability makes it possible to perform a financial transaction multiple times even if I do not have the sufficient balance in my wallet thus making it possible for me to steal money and perform any financial fraudulent activity on your application.
Description:
A race condition occurs when multiple threads simultaneously access the same shared code, variables, files, etc. without locking or synchronization, resulting in inconsistency of the output.
The application has multiple functions to perform financial transactions like buy airtime, pay for other utility bills, send money to an account or a bank, while all of these functions exists, I decided to test against the buy airtime function which is the easiest to carry out and if any error occur, it should have the barest minimum risk impact to your organization. While testing I had 188 naira on my account, I decided to test your application against race condition vulnerability thus upon the request to buy the airtime, I sent the request multiple times simultaneously and I was able to buy a 188 airtime multiple times.
Steps to reproduce:
1. Logged into my app account
2. Visit the VAS page at https://user.website.com/vas
3. Click on the corresponding network provider
4. Enter the necessary details like the amount and phone number 5. Sending the request, a POST request similar to this will be made
POST /bill/airtime HTTP/1.1
Host : api.website.net
Connection : close
Content-Length : 91
sec-ch-ua : “Google Chrome”;v=”87", “\”Not;A\\Brand”;v=”99", “Chromium”;v=”87"
Accept : application/json, text/plain, */*
Authorization : Bearer
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsidGhyaXZlbW9uaS13ZWIt c2VydmljZSJdLCJ1c2VyX25hbWUiOiJpdHNfYWZvbGljQHdlYXJlaGFja2Vyb25lLmNvb SIsInNjb3BlIjpbInJlYWQiLCJ3cml0ZSJdLCJleHAiOjE2MDgwMTYxOTMsImF1dGhvcm l0aWVzIjpbImFnZW50Il0sImp0aSI6ImZmOWNmMThkLWVkYmEtNDg3NS1hZTYwLWM2YmM
0YWVjOWU2YyIsImNsaWVudF9pZCI6InVzZXIifQ.QN77sjK0Ic67EiDbyezsFVXsQzJqF 7rIXBeaQsk9bHw
sec-ch-ua-mobile : ?0
User-Agent : Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36 Content-Type : application/json
Origin : https://user.website.com
Sec-Fetch-Site : cross-site
Sec-Fetch-Mode : cors
Sec-Fetch-Dest : empty
Referer : https://user.website.com/
Accept-Encoding : gzip, deflate
Accept-Language : en-US,en;q=0.9,hi;q=0.8
{ “amount” : “50” , “phoneNumber” : “08133446104” , “serviceID” : “airtel” , “user Id” : “TM160*****90560” }
6. A possible Pseudo code for this transaction might be this
Read account balance from ACC_From
Read account balance from ACC_TO
If (amount <= ACC_From)
{
Update ACC_TO
Update ACC_From
status= “transaction successful”
}
else
status= “transaction failed”
7. Looking at this code, we can see that the application first checks if the source account balance is less than or equal to the amount before the transaction, if it is then the transaction will be carried out successfully, else fail.
8. Now to exploit this vulnerability, I had 188 naira only in my account, I initiated a buy 188 naira recharge card transaction. While performing this transaction, I sent it multiple times simultaneously.
9. The application checked if my account balance is less than or equal to 188 then it performed the transaction. Now before the application was able to update the wallet balance with the new balance after the first successful transaction, the other requests were carried out successfully because they occurred
simultaneously.
10.Using a tool call Turbo Intruder, I was able to exploit this vulnerability
Impact:
While I only tested against the buy airtime functionality as this is the easiest functionality for me to test against because of its requirement and the possible impact I might cause if I test against other functionality. I believe this vulnerability should be producible on other end-points that perform financial transactions because you are making use of the same API domain.
Remediation:
See the following articles on a detailed explanation on what this vulnerability is and how to fix this vulnerability:
https://medium.com/in-the-weeds/fixing-a-race-condition-c8b475fbb994 https://github.com/mperham/sidekiq/wiki/Ent-Unique-Jobs
https://resources.securitycompass.com/blog/moving-beyond-the-owasp-top-10-part-1-ra ce-conditions-2