How Worktrunk Prevents TOCTOU Vulnerabilities in Hook Execution

Worktrunk eliminates Time-of-Check-to-Time-of-Use (TOCTOU) race conditions by freezing the exact set of hooks permitted to execute at the moment the user crosses the approval boundary, then using that immutable snapshot for the entire operation.

Worktrunk, a Rust-based git workflow automation tool in the max-sixty/worktrunk repository, implements a frozen hook plan architecture to secure command execution against TOCTOU vulnerabilities. When users run commands like wt merge or wt step, the tool must ensure that the hooks approved for execution cannot be modified between the approval check and the actual execution. By capturing an immutable HookPlan at the consent boundary, Worktrunk guarantees that what the user approves is exactly what runs, regardless of subsequent repository changes or file system races.

Understanding the TOCTOU Risk in Hook-Based Workflows

Time-of-Check-to-Time-of-Use vulnerabilities occur when a program checks a condition, then acts on it after a delay during which the condition could change. In hook execution, this represents the window between discovering which hooks exist and actually spawning the subprocess. A malicious actor or race condition could modify hook scripts after the user approves the operation but before execution begins, leading to arbitrary code execution with the user's privileges. Worktrunk addresses this by removing the time window entirely through plan-backed execution.

The Frozen Hook Plan Architecture

Constructing the Immutable HookPlan

When a command that may invoke hooks reaches the approval prompt, Worktrunk builds a HookPlan containing the exact list of hook commands permitted for that operation. This plan is captured before any state-changing actions occur.

According to the source code in src/commands/hook_plan.rs, this design explicitly "closes the approval-boundary TOCTOU" by creating an immutable structure that cannot be altered after user consent:

// At the approval boundary
let approved_plan = HookPlan::approve(&project_config, &command_args)?;

The top-level comments in lines 1-7 of src/commands/hook_plan.rs document this safety mechanism, ensuring that once the user sees the approval prompt, the set of hooks is frozen and cannot mutate even if the underlying configuration changes.

The Approval Boundary Pattern

The approval UI is shown exactly once, and the snapshot of the hook plan is used for the entire operation. Because the plan cannot be mutated after the user's consent, any later changes to the repository—such as a newly added hook script or modified configuration—cannot affect the already-approved execution path.

As implemented in src/commands/hook_plan.rs (lines 440-447), this design ensures the approval prompt remains "byte-identical" and "TOCTOU-covered," guaranteeing that no hook can be inserted or altered after the user reviews the operation but before execution completes.

Plan-Backed Hook Execution

The actual hook runner in src/commands/hooks.rs receives the pre-approved HookPlan and iterates over the cached list rather than re-reading the project configuration each time a hook launches. This eliminates the window between checking which hooks exist and actually launching them.

The module header in src/commands/hooks.rs (lines 18-22) explicitly notes this "Plan-backed (the TOCTOU-covered set)" approach:

// Later, after any mutating work has happened
for hook in approved_plan.iter() {
    // No re-reading of config; the list is immutable
    HookExecutor::run(hook)?;
}

By using the frozen plan rather than querying the filesystem or configuration for each hook execution, Worktrunk ensures that the exact commands approved by the user are the commands that execute, even if minutes pass between approval and completion.

TOCTOU Protection for Reference Updates

Beyond hook execution, Worktrunk extends TOCTOU protection to git ref updates. For operations that modify refs—such as push, merge, or promote—the tool snapshots the target SHA before performing any mutating actions. This snapshot is then used for the ref update, guaranteeing that the ref being updated has not changed between the check and the write.

In src/commands/worktree/push.rs (lines 104-110), the code shows this early snapshot pattern:

// Capture SHA before any race window
let target_sha = repo.resolve_ref("refs/heads/main")?;
let push = Push::new(&repo, target_sha);
// ... perform push safely
push.execute()?;

This same pattern appears in src/commands/merge.rs, which utilizes the frozen hook plan for merge-related hooks while ensuring the merge target remains stable throughout the operation.

Summary

  • Frozen Hook Plans: Worktrunk constructs an immutable HookPlan at the approval boundary in src/commands/hook_plan.rs, freezing the exact set of hooks before any state changes occur.
  • No Configuration Re-reading: The hook executor in src/commands/hooks.rs uses the cached plan rather than querying the filesystem, eliminating the TOCTOU window between check and use.
  • Atomic Ref Snapshots: Operations like pushes in src/commands/worktree/push.rs capture target SHAs before mutating work, preventing race conditions in ref updates.
  • Single Approval Boundary: By showing the approval prompt once and using a byte-identical plan for the entire operation, Worktrunk ensures that approved operations cannot be altered by subsequent filesystem changes.

Frequently Asked Questions

What is a TOCTOU vulnerability in the context of hook execution?

A TOCTOU (Time-of-Check-to-Time-of-Use) vulnerability in hook execution occurs when a program verifies which hooks are present and safe to run, but then executes them after a delay during which the hook scripts could be modified. This creates a window where malicious code could replace approved hooks, leading to privilege escalation or arbitrary code execution with the user's credentials.

How does the HookPlan prevent race conditions?

The HookPlan prevents race conditions by capturing the exact list of permitted hooks and their configurations at the moment the user approves the operation. As implemented in src/commands/hook_plan.rs, this plan is immutable and "closes the approval-boundary TOCTOU." Once frozen, the plan travels with the operation through completion, ensuring that even if the underlying repository configuration changes, the execution uses only the originally approved hooks.

Does this protection apply to all Worktrunk commands?

The TOCTOU protection applies to all commands that invoke hooks, including wt merge, wt remove, and wt step, as well as reference-modifying operations like pushes. Any command that crosses the approval boundary receives a frozen plan or snapshot before performing mutating actions, ensuring consistent protection across the codebase.

Where is the frozen plan created in the source code?

The frozen plan is created in src/commands/hook_plan.rs, where the HookPlan struct is defined with comments explaining the TOCTOU-covered approval boundary. The execution logic that respects this frozen state resides in src/commands/hooks.rs, which receives the pre-approved plan and runs hooks from the cached list without re-reading configuration files.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →