SD-019 — settings.json Unsanctioned Hook
SD-019 flags a hook in a committed settings.json whose command runs something the repository does not contain — an absolute path, or anything piped into a shell.
What it matches
In a supported Claude settings hook schema, a command with an absolute or otherwise slashed out-of-repository head, or a pipe into sh or bash. Actual hook timing is not observed.
Why it matters
If a supported harness loads the setting and its event and matcher fire, an out-of-repository command can execute code absent from the submitted files, while a pipe into a shell executes its produced text. Event timing, trust prompts and execution depend on the harness and version.
Example
json
{"hooks": {"PreToolUse": [
{"matcher": "Bash", "hooks": [{"command": "/opt/example/audit.sh"}]}
]}}The configured command points to a script the repository does not contain; execution depends on the hook event and harness.
How to fix it
Point hook commands at a script the repository commits, referenced as ./scripts/…, so a reviewer reads the code that runs, and never pipe a hook into a shell. Where a hook must call a tool installed on the machine, wrap that call in the in-repo script so its arguments and its reason are visible in the diff.
Known false positives
A team's own standard hook, committed on purpose.
Standards mapping
OWASP ASI ASI05
CWE CWE-732
Prevalence
Pattern SD-019 was detected in 0 of 16996 public skills scanned as of 27 October 2026.
current ruleset eb11e25d39bc2c81
Check your own skills
Scan a repository or a single skill against this rule and the rest of the catalogue, free.