fix(hooks): eliminate TOCTOU race in stop-feedback.sh plugin root lookup#151
Open
xiaolai wants to merge 1 commit intotanweai:mainfrom
Open
fix(hooks): eliminate TOCTOU race in stop-feedback.sh plugin root lookup#151xiaolai wants to merge 1 commit intotanweai:mainfrom
xiaolai wants to merge 1 commit intotanweai:mainfrom
Conversation
The hook wrote the plugin root path to /tmp/pua-plugin-root, then the heredoc instructed Claude to execute: bash "$(cat /tmp/pua-plugin-root)/hooks/sanitize-session.sh" ... Between the write and Claude's bash execution, a local user controlling /tmp/ could replace the file to redirect execution to an arbitrary script. Fix: remove the temp-file indirection entirely. CLAUDE_PLUGIN_ROOT is already set in the hook environment (and in Claude's bash context) by Claude Code — use it directly. The _PLUGIN_ROOT computation block is also removed as it is now dead code. Co-Authored-By: Claude Code <noreply@anthropic.com>
This was referenced Apr 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What's broken
hooks/stop-feedback.shresolves the plugin root path and writes it to a temporary file:Then, inside a heredoc, it instructs Claude to execute:
bash "$(cat /tmp/pua-plugin-root)/hooks/sanitize-session.sh" ...There is a time window between when the hook writes
/tmp/pua-plugin-rootand when Claude's bash execution reads it back. On a system where/tmp/is world-writable, a local user can replace the file contents between those two moments, redirecting thebashcall to an arbitrary script. This is a classic TOCTOU (Time-of-Check-Time-of-Use) race.Fix
Remove the temp-file indirection entirely.
CLAUDE_PLUGIN_ROOTis set in the hook's execution environment by Claude Code and is also available in Claude's bash context. Use it directly:The
_PLUGIN_ROOTcomputation block (theif [[ -n "${CLAUDE_PLUGIN_ROOT:-}" ]]block) is removed as dead code since it was only used to produce the now-eliminated temp file.This is a 9-line removal and a 1-word change — fully mechanical with no behavioral change in the normal code path.