You likely know the old saying about “those of us who assume” and what it does to people. Although you typically use this phrase when discussing person-to-person interactions, you can also apply it to application programming. Applications are complex because they often run multiple tasks in a short time. On the other hand, they’re unintelligent because they can only do what the programmer tells them to do. Unfortunately, attackers can use this digital tug-of-war between complexity and unintelligence to undermine an application’s security.
By understanding the definition of race condition and its impact on application security, you can mitigate risk more effectively.
What is a race condition?
A race condition is when an application attempts to execute multiple independent processes (“threads”) simultaneously to accomplish multiple tasks at once rather than performing in the appropriate sequence. While running multiple processes (“multi-threading”) improves application performance by using computing resources more efficiently, running them simultaneously creates problems when both processes attempt to access the same resource at the same time, causing what’s known as a “collision.”
Four types of race conditions exist:
- Critical: Both processes execute, which prevents the application from acting as intended.
- Noncritical: Both processes execute but cause no real issues with what the application does.
- Read-write-modify: Both processes access the resource and return a different value, undermining data integrity.
- Check-then-act: Both processes check a value, but the first one changes, which means the other process reads the value as null.
By not defining the order in which the processes should run, they “race” against each other to get to the resource first, leading them to “run into” each other. Typically, the race condition simply causes the application to malfunction. However, attackers can exploit a race condition vulnerability.
How do attackers exploit a race-condition vulnerability?
When attackers exploit a race condition vulnerability, they turn the two-processes sprint into a three-person competition. They use the confusion that the lack of processing order creates to trick the system. Since no specific order exists, they can “get ahead” of the approved processes and manipulate the resource, hiding within the process flows.
Time-of-Check and Time-of-Use (TOCTOU)
A TOCTOU attack exploits the time between when the process “looks” at the resource and “interacts” with it.
Prerequisites for attackers successfully completing a TOCTOU attack are:
- Multiple processes concurrently access or modify a resource.
- Attackers can modify the resource.
- A race condition exists when accessing a resource.
As an analogy, if two people (processes) are running a race, a third person (attacker) joins from off the racetrack and moves the finish line.
When applications change resources, they often create temporary files before the final file. When attackers want to leverage a race condition vulnerability, they can make symlinks, files that point to other files that they control. By “mimicking” the temporary file with a symlink, they can insert malicious code to undermine the application’s security.
Prerequisites for attackers successfully using symlinks are:
- Attackers can create symlinks on the target host.
- Attackers can use and copy malicious code to temporary files.
- The target host’s temporary file creation processes are insecure.
As an analogy, if two people (processes) are running a race, a third person (attacker) changes the route to send them somewhere off course.
Common Weakness Enumerations (CWEs) and Race Conditions
The Common Weakness Enumeration (CWE) list defines various conditions across software, firmware, hardware, or service components that could contribute to introducing vulnerabilities. According to the CWE, “Concurrent Execution using Shared Resouce with Improper Synchronization” is listed as 21 out of 25 Most Dangerous Software Weaknesses for 2023.
Some additional weaknesses identified include:
- Insufficient control flow management: Code does not manage control flow during execution, enabling unexpected modification
- Signal handler race condition: Functions supporting asynchronous actions can violate the code’s assumptions, leading to a race condition.
- Race condition within a thread: Two threads simultaneously use a resource, undermining the data’s integrity.
- Context switching race condition: Actions switch between access privilege types or other security boundaries, allowing attackers to modify or misrepresent behavior during the switch
- Race Condition During Access to Alternate Channel: An alternate channel for communicating with an authorized user is accessible to other actors, meaning attackers could access the channel before the authorized user does.
- Permission Race Condition During Resource Copy: The resource permissions or access controls are not set until a resource copy/clone is complete, exposing it to other spheres.
- Race Condition for Write-Once Attributes: A hardware design flaw enables an untrusted software component to send write cycles to the write-once register before the trusted software component.
- Hardware Logic Contains Race Conditions: A logic circuit flaw creates a timing error that, if in access control logic, attackers can use to circumvent protections.
- Improper Synchronization: Multiple processes simultaneously try to access a shared resource that can only be exclusive to one process at a time.
How to Mitigate Race Condition Threats
Some suggestions for protecting your application from race condition threats include:
- Using safe libraries to access resources
- Review code for improper access functions, like chown(), tempfile(), and chmod(),
- Controlling the execution flow with synchronization
- Using a static application security testing (SAST) tool to scan code
- Looking for resource access concurrency problems
Qwiet AI: Automated Code Scanning to Identify Race Condition Vulnerabilities
With Qwiet AI’s preZero platform, you can check for vulnerabilities in millions of lines of code in minutes, enabling you to get the accurate and detailed findings necessary to protect your application from SQL injections.
PreZero identifies vulnerabilities and then adds context to help you prioritize remediation activities by giving you visibility into the ones attackers can actually exploit. Using Qwiet AI, you can eliminate thousands of false positives for a noise-free list that prioritizes your riskiest code, enabling faster time-to-market.
Take our preZero platform for a free spin to see how Qwiet AI can help you identify and remediate race condition vulnerabilities.