A common sign is a file-system check immediately followed by an action on the same path, without reusing a validated handle. Patterns such as checking existence or permissions and then opening, writing, or creating by pathname are especially suspect. The risk grows when the code runs with elevated privileges or touches attacker-controlled directories.
How TOCTOU Vulnerability Shows Up in Code
TOCTOU problems usually reveal themselves as a split decision: the program checks a condition, then later acts on the same object as if nothing changed in between. The most common pattern is pathname-based file logic, where code checks existence, ownership, type, or permissions and then opens, writes, deletes, or creates by the path instead of by a stable handle.
That pattern becomes especially suspicious when the check and the action are separated by additional work, callbacks, logging, IPC, or any delay that gives another process time to swap the target. If the code can be redirected to a different file, symlink, or directory entry after the check, the validation was only momentary and not authoritative.
A second sign is duplicated authority. If the code re-derives trust from the filesystem more than once, or repeats a permission decision without locking the object it decided on, it may be assuming a stable state that does not exist. In secure designs, the check and the use are bound to the same object reference, not merely the same textual path.
Code Patterns That Make the Race Window Dangerous
TOCTOU risk is highest when the code uses separate operations that are individually sensible but collectively unsafe, such as stat-then-open, access-then-create, or lstat-then-write. The bug is not the existence of a check, it is the fact that the check does not survive the gap before use.
Any pattern that resolves names twice is worth scrutiny, particularly if it crosses privilege boundaries or runs in a directory an attacker can modify. A privileged process that trusts a user-controlled path is a classic signal, because even a tiny race window can be enough to redirect the operation toward a sensitive target.
Another useful indicator is missing atomicity. If the code does not use an atomic operation, a file descriptor, an exclusive create, or a similar mechanism that makes the decision and action inseparable, then the pathname itself remains the weak link. A secure review should ask whether the target is being acted on through a stable handle or merely rediscovered by name.
What Reviewers Should Look For First
Start by tracing any security check to the exact object later used by the operation. If the code checks a path and later opens a path, the answer is not good enough unless the later operation is guaranteed to refer to the same object state. The same applies to permission checks, type checks, existence checks, and ownership checks.
Also look for hidden opportunities to interleave attacker action between those steps. Filesystem hooks, network calls, process scheduling, retries, and error handling can all widen the window. The more indirect the path from validation to use, the easier it is for an attacker to change the target after the code has already made its decision.
For deeper examples of how name-based trust breaks in practice, the The 52 NHI Breaches Report and the United Nations Breach show how exposed credentials, misconfiguration, and weak access assumptions create exploitable openings around trusted paths and resources.
Risk and Threat Considerations
TOCTOU becomes materially dangerous when an attacker can modify the checked object, or substitute a different one, during the interval between validation and use. That makes the issue more than a correctness bug, because it can become privilege escalation, unauthorized file overwrite, or unintended access to a protected resource.
Failure mechanism: the program validates one state of a resource, then acts on a different state after the resource has been swapped, renamed, or replaced, often through a pathname race or symlink substitution.
Impact: a low-privilege actor may cause a privileged process to operate on the wrong file or directory, turning a local race into data corruption, sensitive file exposure, or code execution in the worst cases.
Standards & Framework Alignment
This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.
MITRE ATT&CK addresses the attack and risk surface, while CIS Controls v8, NIST SP 800-53 Rev 5, OWASP ASVS and NIST CSF 2.0 set the governance and control requirements practitioners need to meet.
| Framework | Control / Reference | Relevance |
|---|---|---|
| MITRE ATT&CK | T1574 — Hijack Execution Flow | TOCTOU races can redirect a privileged process to an attacker-chosen target. |
| Recommendation — Hunt for raceable path handling and replace name-based trust with atomic object access. | ||
| CIS Controls v8 | CIS-5 — Account Management | Privileged code paths raise the impact of race conditions on sensitive operations. |
| Recommendation — Restrict privileged execution paths and review who can trigger sensitive file operations. | ||
| NIST SP 800-53 Rev 5 | SI-10 — Information Input Validation | Validation gaps are central when code checks then later uses attacker-influenced paths. |
| Recommendation — Validate and bind the resource at the point of use, not only at the point of check. | ||
| OWASP ASVS | V15 — Secure Coding and Architecture | TOCTOU is a secure-design defect involving unsafe sequencing and trust boundaries. |
| Recommendation — Design file and resource handling so validation and use cannot be separated by a race. | ||
| NIST CSF 2.0 | PR.AA-05 — Least Privilege | Privilege amplifies the impact of race conditions in file and resource handling. |
| Recommendation — Limit the blast radius of any race by minimizing the privileges of the calling process. | ||
Practitioner Guidance
What to verify: confirm whether the code acts on a stable object handle after validation, not on a re-resolved name. If the operation is security-sensitive, treat any check-then-use sequence on attacker-influenced paths as suspect until proven atomic.
Decision rule: if the code is checking a pathname and then performing a privileged action on that same pathname, prefer an atomic open-or-create pattern, a validated descriptor, or a design that removes the name lookup from the trust decision entirely.
Practitioner takeaway: The key question is not whether a check exists, but whether the check and the use are bound to the same immutable object state.
Related resources from NHI Mgmt Group
- What are the signs that archive handling code is vulnerable to Zip Slip style attacks?
- How can organizations counter AI-driven cyber attacks?
- What are the signs that Android file sharing code is vulnerable to path traversal?
- What are the signs that an organisation is still vulnerable to credential-based attacks?