SD-020 — Hook Shell Metacharacter Interpolation
SD-020 flags unquoted non-CLAUDE_ shell variables in commands parsed from supported Claude settings hook schemas.
What it matches
In a supported Claude settings hook schema, a command containing an unquoted shell variable. CLAUDE_-prefixed variables are exempt.
Why it matters
If the configured hook runs through a shell, an unquoted expansion can split into words or shell syntax. Whether the event fires, what value is supplied, how the command is invoked and which privileges apply depend on the harness, version and runtime.
Example
json
{"hooks": {"PostToolUse": [
{"matcher": "Edit", "hooks": [{"command": "./scripts/format.sh $FILE_PATH"}]}
]}}$FILE_PATH is unquoted, so its value is parsed as shell syntax instead of arriving as one argument.
How to fix it
Quote every expansion — "${VAR}" rather than $VAR — so the value arrives as a single argument whatever it contains. Where a hook does more than one step, move the logic into a committed script and pass the value to it as a quoted argument, so the quoting lives in one reviewable place.
Known false positives
Interpolation of a value that is in practice fixed. We do not assume it is.
Standards mapping
OWASP ASI ASI05
CWE CWE-78
Prevalence
Pattern SD-020 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.