Hooks added to settings should require explicit per-hook user review (no silent activation)
<img width="1340" height="586" alt="Image" src="https://github.com/user-attachments/assets/50fea1cb-628e-4cbf-bd28-5c245478484a" />
Problem
Hooks are one of the highest-authority extension points in Claude Code: a PreToolUse/SessionStart hook is arbitrary shell code that runs on every session, often with full user permissions. Today, nothing surfaces newly added hooks to the user if the trust prompt is bypassed or already accepted for that scope:
- The undocumented
hasTrustDialogHooksAccepted: truekey in~/.claude.jsonsilently disables the "Hook PreToolUse:X requires confirmation" prompts for an entire project (see #54702). - A third-party tool, a rogue Claude agent session, or a tutorial can add hooks to
~/.claude/settings.json/.claude/settings.json(or flip that key), and the user has no notification that new executable code was wired into their sessions.
So it is possible for anyone with write access to these files — including an agent itself — to silently gain persistent code execution on every future Claude Code session.
How Codex (OpenAI) solves this
OpenAI Codex CLI has a dedicated Hooks review UI: every lifecycle hook loaded from config/plugins is listed per event (PreToolUse, SessionStart, UserPromptSubmit, …) with Installed / Active / Review counters, and hooks whose count in the Review column is non-zero are not allowed to run until the user reviews and approves them. A banner states "N hooks need review before they can run." Newly installed hooks always land in the review state — there is no key that pre-approves them.
(Screenshot available on request; it's the Hooks panel in Codex showing "⚠ 3 hooks need review before they can run." with Review counts per event.)
Proposal
- Track which hooks (event + command) the user has explicitly approved. Any hook not in that set starts in a pending-review state and does not execute.
- Show a persistent notice — e.g. "⚠ N hooks need review" in
/hooksand at session start — until reviewed. - Remove or gate the
hasTrustDialogHooksAcceptedbypass: a boolean that blanket-trusts all future hooks in a scope defeats the review boundary (as documented in #54702). Approval should be per-hook, not per-scope. - Optionally: notify when
settings.jsonhook sections change externally during a session.
References
- #54702 — undocumented
hasTrustDialogHooksAcceptedkey bypasses hook trust prompts - #5572 — the key exists but is not settable via
claude config set(same internal flag) - #20258 — hooks security disclaimer buried in docs