Metastatic.Analysis.BusinessLogic.TOCTOU (Metastatic v0.10.4)

View Source

Detects Time-of-Check-Time-of-Use (TOCTOU) race condition vulnerabilities.

TOCTOU vulnerabilities occur when there is a time gap between checking a condition and using the result of that check, allowing the state to change between the check and use phases. This is a common source of security vulnerabilities and bugs, especially in file operations and resource access.

Cross-Language Applicability

This is a universal vulnerability pattern that applies to all languages:

  • Python: os.path.exists() followed by open()
  • JavaScript/Node.js: fs.existsSync() followed by fs.readFileSync()
  • Elixir: File.exists?() followed by File.read()
  • Go: os.Stat() followed by os.Open()
  • Java: file.exists() followed by new FileInputStream(file)
  • Rust: path.exists() followed by File::open()
  • Ruby: File.exist?() followed by File.open()
  • C: access() followed by open()

CWE Reference

  • CWE-367: Time-of-check Time-of-use (TOCTOU) Race Condition

Examples

Bad (Python)

if os.path.exists(file_path):
    # Attacker could delete/replace file here
    with open(file_path) as f:
        data = f.read()

Good (Python)

try:
    with open(file_path) as f:
        data = f.read()
except FileNotFoundError:
    handle_missing_file()

Bad (Elixir)

if File.exists?(path) do
  # Race condition window
  {:ok, content} = File.read(path)
end

Good (Elixir)

case File.read(path) do
  {:ok, content} -> process(content)
  {:error, :enoent} -> handle_missing()
end

Bad (JavaScript)

if (fs.existsSync(path)) {
    // Race condition window
    const data = fs.readFileSync(path);
}

Good (JavaScript)

try {
    const data = fs.readFileSync(path);
} catch (err) {
    if (err.code === 'ENOENT') handleMissing();
}

Detection Strategy

Detects patterns where:

  1. A check function (exists, can_access, is_valid, etc.) is called in a condition
  2. A corresponding use function (read, write, open, delete, etc.) appears in the same block
  3. The same resource (variable, path) is referenced in both operations

The analyzer looks for:

  • File existence checks followed by file operations
  • Permission checks followed by privileged operations
  • Resource availability checks followed by resource use
  • Null/presence checks with operations between check and use