Time-of-check to time-of-use is a design problem, not a lint warning
A time-of-check to time-of-use (TOCTOU) flaw appears when a program verifies a condition and then acts on it, and the state can change between the two steps. The window is often microseconds, which makes the bug easy to dismiss and hard to reproduce reliably.
Why the reader needs this
Almost every access-control check has this shape. The code confirms that a user owns a resource, then performs the operation. If the resource can change hands in between, the check no longer describes the state the operation sees.
Technical context
Two families exist. In a filesystem TOCTOU, a program checks that a path is safe, then opens it, and an attacker swaps a symlink in between so the open follows the link. In an application TOCTOU, a service reads a record, validates a field, and writes an update, while a concurrent request changes the same record. The database engine does not protect the application's logic unless the read and the write are in one transaction with an appropriate lock.
Where the defect hides
The check-then-act pattern is idiomatic, so it spreads. Authorisation middleware validates a resource, and the handler fetches it again by identifier. A balance is read, compared with an amount, and written back, so two concurrent requests both pass the comparison. A file is validated by path, then reopened by name. Each of these reads the same state twice and trusts that it did not move.
Defensive implications
Make the check and the use one operation. In a database, use a conditional update that includes the ownership or version in its WHERE clause and verify the affected row count, rather than reading and then writing. Prefer row locks or optimistic concurrency with a version column. In the filesystem, open the file once and operate on the file descriptor, with O_NOFOLLOW where the platform supports it, instead of validating a path and reopening it. Test by running two requests concurrently against the same record and confirming the second fails cleanly rather than succeeding incorrectly.
References
- MITRE, CWE-367: Time-of-check Time-of-use (TOCTOU) Race Condition
- PostgreSQL, Transaction isolation
- man7.org, open(2)
Top comments (0)