time-of-check to time-of-use

The gap between checking a file and using it is where attackers live.

A TOCTOU bug happens when code verifies something about a path — that it exists, that it's owned by the right user, that it's safe to read — and then, a moment later, acts on that same path as if nothing could have changed in between. If an attacker can swap the file in that gap, the check they just passed no longer means anything.

Everything below is simulated in your browser for illustration — this static site can't run real processes or touch a real filesystem. The "real results" and "scanner" panels further down show actual captured output from the exploiter and scanner CLI tools in this repo, which do the real thing against real sample programs.
race window secret.txt symlink → attacker CHECK USE
1 · checkos.access() / os.stat() confirms the file looks safe
2 · swapthe path is replaced with a symlink to another file
3 · useopen() re-resolves the path — and follows the swap
simulated

Watch a race window get hit

A self-contained browser simulation — no real process, no real filesystem. Each attempt tries to land inside the race window; a wider window and a faster attacker both raise the odds, the same way they do in the real exploiter's thread-contention approach.

race simulator

illustrative only
0
attempts
0
hits
0%
hit rate
race window landed inside missed
real data

Actual hit rates, captured with the CLI

Output from exploiter verify, run against one vulnerable/patched pair — real subprocesses, real symlink swaps, on a real (sandboxed) filesystem. Unlike the simulator above, nothing here is randomized for effect.

exploiter verify

real

loading run data…

real data

What the static scanner catches

Output from scanner scan samples/ — an AST-based pass over the sample programs that flags check-then-use pairs on the same path within a function. Every snippet below is the actual flagged code.

scan report

real

loading scan data…