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 byopen() - JavaScript/Node.js:
fs.existsSync()followed byfs.readFileSync() - Elixir:
File.exists?()followed byFile.read() - Go:
os.Stat()followed byos.Open() - Java:
file.exists()followed bynew FileInputStream(file) - Rust:
path.exists()followed byFile::open() - Ruby:
File.exist?()followed byFile.open() - C:
access()followed byopen()
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)
endGood (Elixir)
case File.read(path) do
{:ok, content} -> process(content)
{:error, :enoent} -> handle_missing()
endBad (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:
- A check function (exists, can_access, is_valid, etc.) is called in a condition
- A corresponding use function (read, write, open, delete, etc.) appears in the same block
- 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