Glossary

What is TOCTOU: when the state changes between the check and the use

TOCTOU (time-of-check to time-of-use) is a race condition where state changes after a check. How it works and how to defend: combine check and use in one step.

Published 2026-11-15 Updated 2026-11-15 5 min read
On this page

TOCTOU (time-of-check to time-of-use) is a problem where the state of something changes between the moment it is checked and the moment it is used. This page explains how it works and how to prevent it (no attack steps).

What TOCTOU is

Programs often work as "check, then use if it looks fine": for example, "check that this file may be written, then open and write it." But there is a small time gap between the check and the use. If another program or request changes the target in that gap, the result of the check no longer holds.

MITRE's CWE-367 describes this as a product that checks the state of a resource before using it, where the state can change between the check and the use in a way that invalidates the check. CWE (Common Weakness Enumeration) is a shared catalog of the weaknesses behind vulnerabilities. TOCTOU is a kind of race condition, where the outcome depends on the timing of things that run at the same time.

Why it happens

1. Check: may this file be written? → OK
2. Gap: another process replaces what that name points to
↓ the check result no longer matches reality
3. Use: the program writes to a target it never checked
When check and use are separate steps, the target can be swapped in between and the check result goes stale.

According to CWE-367, consequences can include access to resources that should be off limits, resources changed in unwanted ways, and missing logs. The gap may be short, but in systems that run many things at once it is hit repeatedly, not just by chance.

Where it shows up

PlaceCheckUseWhat goes wrong
File handlingExistence or permission checkOpen or writeThe file is swapped after the check
Web app stock or balanceSELECT the remaining countUPDATE to reduce itTwo concurrent requests both pass and exceed the limit
Payments and sign-upsIs it still unprocessed?Run the actionA double submit runs it twice
File uploadsInspect the contentStore or publishThe content changes after inspection

For upload inspection, see also file upload vulnerabilities.

Defense: don't separate check from use

1

Stop checking before using

CWE-367's most basic advice is not to perform a check before the use. Use the resource directly and handle the error if it fails. That removes the gap itself.

2

Use file descriptors, not paths

Open the file first, then check state and write through the open file descriptor. Looking up the same path name repeatedly can point to a different target each time. Flags such as O_NOFOLLOW (do not follow symbolic links) and calls such as openat (open relative to a directory) help too; what is available depends on the OS.

3

Use conditional updates and transactions for databases

Instead of "SELECT to check, then UPDATE", use one UPDATE that includes the condition (for example, decrement only when the count is 1 or more). When several statements are involved, use a transaction with a suitable isolation level and row locks.

4

Lock before the check

If you use locks, take them before the check, as CWE-367 says. Locking after it does not guarantee that the checked target is the one you use.

5

Stop double execution with idempotency keys

For payments and sign-ups, give each request a unique key (an idempotency key) and run the action only once per key.

How to check your own code

Do this in code you build or manage.

  1. Find places where the checking code and the using code are separate calls (existence check then open; SELECT then UPDATE)
  2. For each, ask whether the check can be dropped and the step made a single operation
  3. Write a test that sends the same request several times at once, and confirm only one is applied
  4. Never try this against someone else's service; use your own environment

This site's view: put the check inside the same operation as the use

TOCTOU is not "someone forgot the check." The check exists; it is just separated from the use. Adding more checking code does not fix that. The fix is to put the check inside the same atomic operation as the use, not to add it as an extra step. Learning it next to IDOR helps in reviews: both are "a check exists but doesn't do its job" bugs.

Sources (primary)

  • MITRE CWE-367: Time-of-check Time-of-use (TOCTOU) Race Condition — cwe.mitre.org (definition, consequences, mitigations)
  • The concrete techniques (O_NOFOLLOW, openat, idempotency keys, transactions) are described as general implementation practice; availability varies by OS and database, so check each product's official documentation

Classification

CWE classifies the types of weakness behind vulnerabilities; MITRE ATT&CK classifies attacker techniques. Both are maintained by MITRE and widely used to label vulnerability reports and detection rules.

CWE™: Copyright © 2006–2026, The MITRE Corporation. CWE is a trademark of The MITRE Corporation. The MITRE Corporation hereby grants you a non-exclusive, royalty-free license to use CWE for research, development, and commercial purposes. Any copy you make for such purposes is authorized on the condition that you reproduce MITRE’s copyright designation and this license in any such copy. CWE Terms of Use

FAQ

QWhat does TOCTOU mean?
A

It stands for time-of-check to time-of-use. The state of a resource changes between the moment it is checked and the moment it is used. MITRE's CWE-367 describes it as a product that checks a resource's state before using it, where the state can change in a way that invalidates the check. It is a kind of race condition.

QWhere does TOCTOU happen?
A

The classic place is file handling: a program checks whether a file exists or may be written, then opens it in a separate call, and the file can be swapped in between. It also happens in web apps and databases, such as 'check stock, then confirm the order' or 'check the balance, then deduct', when the check and the update are separate steps.

QWhat is the main defense?
A

Combine check and use into one atomic operation. CWE-367 says the most basic advice is to not perform a check before the use. For files, open first and then inspect or act on the open file descriptor. For databases, use a conditional update, or a transaction with locking.

QDoes adding a lock always make it safe?
A

The lock has to be taken before the check, not after. CWE-367 says to ensure locking occurs before the check, as opposed to afterwards. Locking after the check does not guarantee that the thing you checked is the thing you use. A lock also does nothing if its scope is too narrow or other programs ignore it.

QDoes TOCTOU affect web applications?
A

Yes. Examples are saving an uploaded file after it was inspected, decrementing a coupon or stock count after reading it, and payment handlers that must not run twice. If the same request arrives twice at once, both can pass the check. Make the update one conditional operation, and use idempotency keys to stop duplicate execution.

QHow do I look for TOCTOU in my own code?
A

Find places where the checking code and the using code are separate lines or calls. In file code, that is an existence or permission check followed by opening by path. In database code, that is a SELECT to check followed by an UPDATE. Then see whether you can drop the check and make it one operation, and add concurrent-request tests.