Weakness · High

CWE-362: Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')

What it is

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.

Likelihood of exploit: Medium12 exploited in the wildMITRE CWE 4.19.1

Severity (our rating)
High
Likelihood of exploit
Medium
Introduced during
Architecture and Design, Implementation
Exploited in the wild
12 known exploited CVEs

In more detail

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: Exclusivity - the code sequence is given exclusive access to the shared resource, i.e., no other code sequence can modify properties of the shared resource before the original sequence has completed execution. Atomicity - the code sequence is behaviorally atomic, i.e., no other thread or process can concurrently execute the same sequence of instructions (or a subset) against the same resource. 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.

What an attacker can do

  • DoS: Resource Consumption (CPU) (Availability)
  • DoS: Resource Consumption (Memory) (Availability)
  • DoS: Resource Consumption (Other) (Availability)
  • DoS: Crash, Exit, or Restart (Availability)
  • DoS: Instability (Availability)
  • Read Files or Directories (Confidentiality, Integrity)
  • Read Application Data (Confidentiality, Integrity)
  • Execute Unauthorized Code or Commands (Access Control)
  • Gain Privileges or Assume Identity (Access Control)
  • Bypass Protection Mechanism (Access Control)

How to prevent it

Architecture and Design

  • 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).
  • Run your code using the lowest privileges that are required to accomplish the necessary tasks. 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.

Implementation

  • 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.

How to find it

  • 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. 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, or generate incorrect results. Race conditions may be detected with a stress-test by calling the software simultaneously from a large number of threads or processes, and look for evidence of any unexpected behavior. Insert breakpoints or delays in between relevant code statements to artificially expand the race window so that it will be easier to detect.
  • Automated Static Analysis - Binary or Bytecode. According to SOAR, the following detection techniques may be useful: Highly cost effective: Bytecode Weakness Analysis - including disassembler + source code weakness analysis Cost effective for partial coverage: Binary Weakness Analysis - including disassembler + source code weakness analysis
  • Dynamic Analysis with Automated Results Interpretation. According to SOAR, the following detection techniques may be useful: Cost effective for partial coverage: Web Application Scanner Web Services Scanner Database Scanners
  • Dynamic Analysis with Manual Results Interpretation. According to SOAR, the following detection techniques may be useful: Highly cost effective: Framework-based Fuzzer Cost effective for partial coverage: Fuzz Tester Monitored Virtual Environment - run potentially malicious code in sandbox / wrapper / virtual machine, see if it does anything suspicious
  • Manual Static Analysis - Source Code. According to SOAR, the following detection techniques may be useful: Highly cost effective: Manual Source Code Review (not inspections) Cost effective for partial coverage: Focused Manual Spotcheck - Focused manual analysis of source
  • Automated Static Analysis - Source Code. According to SOAR, the following detection techniques may be useful: Highly cost effective: Source code Weakness Analyzer Context-configured Source Code Weakness Analyzer
  • Architecture or Design Review. According to SOAR, the following detection techniques may be useful: Highly cost effective: Formal Methods / Correct-By-Construction Cost effective for partial coverage: Inspection (IEEE 1028 standard) (can apply to requirements, design, source code, etc.)

CWE-362 on MITRE's CWE site

Exploited in the wild: 12 CVEs

Vulnerabilities caused by CWE-362 that attackers have used, from CISA's Known Exploited Vulnerabilities catalog, newest first.

All known exploited vulnerabilities

H2 Security

Found it in your code?

We review where it appears, fix it with your team, and check it was not already used against you.

Talk to our team

T Academy

Stop writing it in the first place

Learn to build software and systems without weaknesses like this one, with practice on real hosts in your browser, every objective checked on the machine.

Start free

Source: MITRE Common Weakness Enumeration, CWE version 4.19.1. CWE is a trademark of The MITRE Corporation.