software development

Race Condition Vulnerabilities in Web Applications

When a web application configured to manage functions in a fixed sequence is required to execute two or more operations concurrently, a race condition attack occurs. This technique takes advantage of a time delay between when a service is introduced and when a safety control occurs. This attack can be carried out either of the two ways, based on multithreaded applications: intrusion incurred by untrusted processes and intrusion incurred by a trustworthy process that could have the same and equal rights.

Different processes may interact with one another without adequate measures. These attacks are also known as Time of Check attack, Time of Use attack, or TOC/TOU attacks. Race condition vulnerabilities happen to be there in the first place due to basic programming errors that developers usually create, and these failures have proven costly. Malicious entities have exploited race conditions for plenty of malicious purposes, i.e., from getting free vouchers to rob money from online accounts and investment firms.

Let’s assume that two parallel execution threads attempt to raise a global variable’s value by 5. Ultimately, then, the global variable would have a value of 10. However, if all threads run concurrently, the execution can be wrong without resource locks or synchronization. When the first thread is doing some manipulations to that global variable, the second thread reads it and starts doing some other manipulations. In this case, the final value would not be as expected.

This occurs since the effect of one thread termination depends on the outcome of the other. When the two threads are executed concurrently, there will be unintended consequences.

Scope of Race Condition Attacks:

Imagine that anything a little more critical is being executed by the two threads of the above example, like exchanging money between bank accounts. To send the money correctly, the program will need to execute these tasks in this sequence; Check if there’s enough balance in the sender’s account, add money to the receiver’s account, and then deduct from the sender’s account. But if you concurrently submit two requests, you may be able to trigger a condition in which the sequence of thread execution changes. In a situation like this, you will end up with a different amount than expected.

Race condition vulnerability was found by Egor Homakov on the Starbucks website. He discovered a way to create an infinite amount of credit on Starbucks gift vouchers for free using different browsers with different cookies.

The prominent Meltdown attack is an example of race condition vulnerability. In the meltdown attack, the weakness is triggered by parallel processing of data retrieval from the memory and authentication of whether or not a user is allowed to access the memory. This flaw makes it possible for a tool to avoid standard privilege checks that separate the attack mechanism from accessing OS data. This loophole results in allowing any unauthorized process to view data and information from any other address connected to the current progress’s state in the memory. In the process of faulty execution, information from an unapproved address will frequently be quickly stacked into the cache of the CPU, from which the information can be recovered.

Real-life attack scenarios:

By submitting numerous requests to the webserver continuously, you can search and manipulate race conditions in web applications. If you want to see whether or not you can withdraw more money than you have in your bank account, using the curl function, you can concurrently send several withdrawal requests to the server.

curl (withdraw 50000) & (withdraw 50000) & (withdraw 50000) & (withdraw 50000) & (withdraw 50000) & (withdraw 50000)

The more demands you file in a brief amount of time, the higher the chances that your attack will work.

Moreover, if you send asynchronous follow-up requests, you will follow a user several times instead of sending an error response. I.e., if you add a fake header containing %s while dropping requests using turbo intruder and paste the following python code:

def followReqs(target, wordlists):
    engine = RequestEngine(endpoint=target.endpoint,
                       concurrentConnections=40,
                       requestsPerConnection=100,
                       pipeline=False
                       )

    for i in range(40):
        engine.queue(target.req, str(i), gate='check')

    engine.openGate('check')
    engine.complete(timeout=60)
def responseHandle(req, interesting):
    table.add(req)

You will see an Attack button. After pressing that, the Turbo Intruder submits 40 queries and scans the status codes. If you see multiple responses with the 201 Generated status, that indicates multiple times you have followed the person.

There is a race condition vulnerability in which you can access multiple consoles offered to free accounts. Most of the websites that provide free consoles have free accounts, standard and premium packages. Free accounts provide only 2 or 3 consoles per user. To break this limit and use unlimited consoles, intrude the GET request using NULL payloads multiple times, like 100 or 200. And then delete any one of the consoles manually from the UI while threads are running.

Conclusion:

As a means to undermine access controls, race conditions are included. Any program that is dependent on mechanisms of access control may be vulnerable. Most of the time, on financial institutions’ websites, hackers exploit race conditions. Since it could lead to unlimited financial benefits for the hacker if a race condition could be discovered on a vital feature such as cash withdrawal, money transfer, or credit card payment. E-commerce platforms, video gaming, and online voting services are other high-risk technologies. Implementing safe concurrency is the secret to avoiding racing conditions. And you can use resource locks too. There will also be a locking feature built-in for programming languages with concurrency abilities that help prevent such conditions. In addition, following secure coding standards, i.e., least privilege concept and auditing code will decrease the program’s chance of breaching.

About the author

Usama Azad

A security enthusiast who loves Terminal and Open Source. My area of expertise is Python, Linux (Debian), Bash, Penetration testing, and Firewalls. I’m born and raised in Wazirabad, Pakistan and currently doing Undergraduation from National University of Science and Technology (NUST). On Twitter i go by @UsamaAzad14