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

mediumpermission_hygiene

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.