Appearance
Why It Matters
SEC368 flags committed Claude settings hook commands that start with a repo-external absolute path such as /opt/... in a shared team-facing config.
This is useful because:
- shared Claude settings in git should stay portable across machines and contributors
- repo-external absolute paths make hook wiring harder to review, reproduce, and safely rotate
- project-scoped wrapper paths rooted in
$CLAUDE_PROJECT_DIRare easier for teams to understand and maintain
What Triggers
This rule applies only to committed Claude settings surfaces:
.claude/settings.jsonclaude/settings.json
It triggers when a hooks entry with type: "command" has a command string that starts with a repo-external absolute path such as:
/opt/.../usr/local/.../etc/.../var/.../private/.../tmp/.../Volumes/.../srv/...
It does not trigger on:
- project-scoped paths rooted in
$CLAUDE_PROJECT_DIR - common system launcher paths such as
/bin/sh -lc ... - fixture-like test/example paths
Examples
Bad:
json
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "/opt/team/hooks/audit.sh"
}
]
}
]
}
}Better:
json
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "$CLAUDE_PROJECT_DIR/scripts/audit.sh"
}
]
}
]
}
}Remediation
- replace repo-external absolute hook commands with project-scoped wrappers
- prefer repo-relative launch paths rooted in
$CLAUDE_PROJECT_DIR - keep shared Claude settings portable across machines