Description
The product contains a concurrent code sequence that requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence operating concurrently.
A race condition occurs within concurrent environments, and it is effectively a property of a code sequence. Depending on the context, a code sequence may be in the form of a function call, a small number of instructions, a series of program invocations, etc. A race condition violates these properties, which are closely related: A race condition exists when an "interfering code sequence" can still access the shared resource, violating exclusivity. The interfering code sequence could be "trusted" or "untrusted." A trusted interfering code sequence occurs within the product; it cannot be modified by the attacker, and it can only be invoked indirectly. An untrusted interfering code sequence can be authored directly by the attacker, and typically it is external to the vulnerable product.
Potential Impact
Availability
DoS: Resource Consumption (CPU), DoS: Resource Consumption (Memory), DoS: Resource Consumption (Other)
Availability
DoS: Crash, Exit, or Restart, DoS: Instability
Confidentiality, Integrity
Read Files or Directories, Read Application Data
Access Control
Execute Unauthorized Code or Commands, Gain Privileges or Assume Identity, Bypass Protection Mechanism
Demonstrative Examples
$transfer_amount = GetTransferAmount();$balance = GetBalanceFromDatabase();
if ($transfer_amount < 0) {FatalError("Bad Transfer Amount");}$newbalance = $balance - $transfer_amount;if (($balance - $transfer_amount) < 0) {FatalError("Insufficient Funds");}SendNewBalanceToDatabase($newbalance);NotifyUser("Transfer of $transfer_amount succeeded.");NotifyUser("New balance: $newbalance");In the following pseudocode, the attacker makes two simultaneous calls of the program, CALLER-1 and CALLER-2. Both callers are for the same user account.CALLER-1 (the attacker) is associated with PROGRAM-1 (the instance that handles CALLER-1). CALLER-2 is associated with PROGRAM-2.CALLER-1 makes a transfer request of 80.00.PROGRAM-1 calls GetBalanceFromDatabase and sets $balance to 100.00PROGRAM-1 calculates $newbalance as 20.00, then calls SendNewBalanceToDatabase().Due to high server load, the PROGRAM-1 call to SendNewBalanceToDatabase() encounters a delay.CALLER-2 makes a transfer request of 1.00.PROGRAM-2 calls GetBalanceFromDatabase() and sets $balance to 100.00. This happens because the previous PROGRAM-1 request was not processed yet.PROGRAM-2 determines the new balance as 99.00.After the initial delay, PROGRAM-1 commits its balance to the database, setting it to 20.00.PROGRAM-2 sends a request to update the database, setting the balance to 99.00void f(pthread_mutex_t *mutex) {
pthread_mutex_lock(mutex);
/* access shared resource */
pthread_mutex_unlock(mutex);
}int f(pthread_mutex_t *mutex) {
int result;
result = pthread_mutex_lock(mutex);if (0 != result)return result;
/* access shared resource */
return pthread_mutex_unlock(mutex);
}Mitigations & Prevention
In languages that support it, use synchronization primitives. Only wrap these around critical code to minimize the impact on performance.
Use thread-safe capabilities such as the data access abstraction in Spring.
Minimize the usage of shared resources in order to remove as much complexity as possible from the control flow and to reduce the likelihood of unexpected conditions occurring. Additionally, this will minimize the amount of synchronization necessary and may even help to reduce the likelihood of a denial of service where an attacker may be able to repeatedly trigger a critical section (CWE-400).
When using multithreading and operating on shared variables, only use thread-safe functions.
Use atomic operations on shared variables. Be wary of innocent-looking constructs such as "x++". This may appear atomic at the code layer, but it is actually non-atomic at the instruction layer, since it involves a read, followed by a computation, followed by a write.
Use a mutex if available, but be sure to avoid related weaknesses such as CWE-412.
Avoid double-checked locking (CWE-609) and other implementation errors that arise when trying to avoid the overhead of synchronization.
Disable interrupts or signals over critical parts of the code, but also make sure that the code does not go into a large or infinite loop.
Use the volatile type modifier for critical variables to avoid unexpected compiler optimization or reordering. This does not necessarily solve the synchronization problem, but it can help.
Run your code using the lowest privileges that are required to accomplish the necessary tasks [REF-76]. If possible, create isolated accounts with limited privileges that are only used for a single task. That way, a successful attack will not immediately give the attacker access to the rest of the software or its environment. For example, database applications rarely need to run as the database administrator, especially in day-to-day operations.
Detection Methods
- Black Box — Black box methods may be able to identify evidence of race conditions via methods such as multiple simultaneous connections, which may cause the software to become instable or crash. However, race conditions with very narrow timing windows would not be detectable.
- White Box — Common idioms are detectable in white box analysis, such as time-of-check-time-of-use (TOCTOU) file operations (CWE-367), or double-checked locking (CWE-609).
- Automated Dynamic Analysis Moderate — This weakness can be detected using dynamic tools and techniques that interact with the software using large test suites with many diverse inputs, such as fuzz testing (fuzzing), robustness testing, and fault injection. The software's operation may slow down, but it should not become unstable, crash
- Automated Static Analysis - Binary or Bytecode High — According to SOAR [REF-1479], the following detection techniques may be useful:
- Dynamic Analysis with Automated Results Interpretation SOAR Partial — According to SOAR [REF-1479], the following detection techniques may be useful:
- Dynamic Analysis with Manual Results Interpretation High — According to SOAR [REF-1479], the following detection techniques may be useful:
Real-World CVE Examples
| CVE ID | Description |
|---|---|
| CVE-2024-38106 | OS kernel stores sensitive data in improperly locked memory, allowing local users to gain privileges by winning a race condition |
| CVE-2022-29527 | Go application for cloud management creates a world-writable sudoers file that allows local attackers to inject sudo rules and escalate privileges to root by winning a race condition. |
| CVE-2021-1782 | Chain: improper locking (CWE-667) leads to race condition (CWE-362), as exploited in the wild per CISA KEV. |
| CVE-2021-0920 | Chain: mobile platform race condition (CWE-362) leading to use-after-free (CWE-416), as exploited in the wild per CISA KEV. |
| CVE-2020-6819 | Chain: race condition (CWE-362) leads to use-after-free (CWE-416), as exploited in the wild per CISA KEV. |
| CVE-2019-18827 | chain: JTAG interface is not disabled (CWE-1191) during ROM code execution, introducing a race condition (CWE-362) to extract encryption keys |
| CVE-2019-1161 | Chain: race condition (CWE-362) in anti-malware product allows deletion of files by creating a junction (CWE-1386) and using hard links during the time window in which a temporary file is created and |
| CVE-2015-1743 | TOCTOU in sandbox process allows installation of untrusted browser add-ons by replacing a file after it has been verified, but before it is executed |
| CVE-2014-8273 | Chain: chipset has a race condition (CWE-362) between when an interrupt handler detects an attempt to write-enable the BIOS (in violation of the lock bit), and when the handler resets the write-enable |
| CVE-2008-5044 | Race condition leading to a crash by calling a hook removal procedure while other activities are occurring at the same time. |
| CVE-2008-2958 | chain: time-of-check time-of-use (TOCTOU) race condition in program allows bypass of protection mechanism that was designed to prevent symlink attacks. |
| CVE-2008-1570 | chain: time-of-check time-of-use (TOCTOU) race condition in program allows bypass of protection mechanism that was designed to prevent symlink attacks. |
| CVE-2008-0058 | Unsynchronized caching operation enables a race condition that causes messages to be sent to a deallocated object. |
| CVE-2008-0379 | Race condition during initialization triggers a buffer overflow. |
| CVE-2007-6599 | Daemon crash by quickly performing operations and undoing them, which eventually leads to an operation that does not acquire a lock. |
Showing 15 of 22 observed examples.
Related Weaknesses
Taxonomy Mappings
- PLOVER: — Race Conditions
- The CERT Oracle Secure Coding Standard for Java (2011): VNA03-J — Do not assume that a group of calls to independently atomic methods is atomic
Frequently Asked Questions
What is CWE-362?
CWE-362 (Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')) is a software weakness identified by MITRE's Common Weakness Enumeration. It is classified as a Class-level weakness. The product contains a concurrent code sequence that requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code...
How can CWE-362 be exploited?
Attackers can exploit CWE-362 (Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')) to dos: resource consumption (cpu), dos: resource consumption (memory), dos: resource consumption (other). This weakness is typically introduced during the Architecture and Design, Implementation phase of software development.
How do I prevent CWE-362?
Key mitigations include: In languages that support it, use synchronization primitives. Only wrap these around critical code to minimize the impact on performance.
What is the severity of CWE-362?
CWE-362 is classified as a Class-level weakness (High abstraction). It has been observed in 22 real-world CVEs.