Rules / CFG067
CFG067 hooks defined in a project-scoped settings file
Severity: warn
OWASP: LLM04:2026 – Supply Chain
OWASP Agentic: ASI04:2026 – Agentic Supply Chain Vulnerabilities: LLM04:2026 now covers the model and data supply chain and refers the agentic one, "including MCP servers and tool registries", to ASI04
CVE: CVE-2025-59536
What cfgaudit checks
Claude Code hooks run automatically on lifecycle events. In a user's global ~/.claude/settings.json they were placed there by the user themselves. In a project-scoped file (.claude/settings.json or .claude/settings.local.json) they were placed there by whoever committed to the repository — and they execute on any developer who opens the project, including ones who have never used Claude Code and don't know hooks exist (CVE-2025-59536).
cfgaudit flags the presence of any hooks in a project-scoped settings file, regardless of their content. This is a separate, lower-severity signal from the content checks: CFG008 / CFG014 / CFG015 / CFG037 / CFG038 / CFG039 still independently flag dangerous hook commands. The rule does not fire on the user-global ~/.claude/settings.json (hooks there are intentional) or on plugin hooks.json files.
A failing hook lets the action through
A hook that fails (its script is missing or exits non-zero without a blocking code) does not stop the event by default. Measured on 2.1.296 with a project UserPromptSubmit hook pointing at a missing script and a local endpoint standing in for the API (#650): with no onFailure, and with "onFailure": "continue", the prompt still reached the model; with "onFailure": "block", which Claude Code honours from a project file, it stopped with "failed; blocking because onFailure is "block"" and no request was made. So a committed hook meant as a guard guards nothing unless it sets onFailure: "block"; on PreToolUse and PermissionRequest an invalid onFailure value drops the whole settings file instead (CFG012).
Trigger example
{
"hooks": {
"PreToolUse": [
{ "matcher": "*", "hooks": [{ "type": "command", "command": "./scripts/setup.sh" }] }
]
}
}
Committed as .claude/settings.json → warn.
Safe alternative
Keep hook definitions out of committed project config. Put them in your user-global ~/.claude/settings.json, or document them as a reviewed onboarding step so each developer opts in knowingly.
References
- CVE-2025-59536
- CFG008 / CFG014 / CFG027 / CFG028 / CFG037 / CFG038: content checks for dangerous hook commands
- CFG016: credential helpers in project-scoped settings (related project-scope trust issue)
Documentation for cfgaudit 1.18.1. Source of this page · Rule implementation