491a45dd43
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
78 lines
2.5 KiB
Bash
78 lines
2.5 KiB
Bash
#!/bin/bash
|
|
# Blocks edits to sensitive or generated files.
|
|
# Used as a PreToolUse hook for Edit|Write operations.
|
|
# Exit 2 = block the action. Exit 0 = allow.
|
|
|
|
# Requires jq for JSON parsing — fail closed if missing
|
|
if ! command -v jq >/dev/null 2>&1; then
|
|
echo "{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"deny\",\"permissionDecisionReason\":\"jq is required for file protection hooks but is not installed.\"}}"
|
|
exit 2
|
|
fi
|
|
|
|
INPUT=$(cat)
|
|
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
|
|
|
|
if [ -z "$FILE_PATH" ]; then
|
|
exit 0
|
|
fi
|
|
|
|
# Protected patterns — add your own
|
|
PROTECTED_PATTERNS=(
|
|
".env"
|
|
".env.*"
|
|
"*.pem"
|
|
"*.key"
|
|
"*.crt"
|
|
"*.p12"
|
|
"*.pfx"
|
|
"id_rsa"
|
|
"id_ed25519"
|
|
"credentials.json"
|
|
".npmrc"
|
|
".pypirc"
|
|
"package-lock.json"
|
|
"yarn.lock"
|
|
"pnpm-lock.yaml"
|
|
"*.gen.ts"
|
|
"*.generated.*"
|
|
"*.min.js"
|
|
"*.min.css"
|
|
)
|
|
|
|
BASENAME=$(basename "$FILE_PATH")
|
|
|
|
for pattern in "${PROTECTED_PATTERNS[@]}"; do
|
|
case "$BASENAME" in
|
|
$pattern)
|
|
echo "{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"deny\",\"permissionDecisionReason\":\"Protected file: $BASENAME matches pattern '$pattern'\"}}"
|
|
exit 2
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Block anything in common sensitive directories (handles both relative and absolute paths)
|
|
case "$FILE_PATH" in
|
|
.git/*|*/.git/*)
|
|
echo "{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"deny\",\"permissionDecisionReason\":\"Cannot edit files inside .git/\"}}"
|
|
exit 2
|
|
;;
|
|
secrets/*|*/secrets/*)
|
|
echo "{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"deny\",\"permissionDecisionReason\":\"Cannot edit files inside secrets/\"}}"
|
|
exit 2
|
|
;;
|
|
.env|.env.*|*/.env|*/.env.*)
|
|
echo "{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"deny\",\"permissionDecisionReason\":\"Cannot edit .env files\"}}"
|
|
exit 2
|
|
;;
|
|
.claude/hooks/*|*/.claude/hooks/*)
|
|
echo "{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"deny\",\"permissionDecisionReason\":\"Cannot edit hook scripts — these enforce security boundaries.\"}}"
|
|
exit 2
|
|
;;
|
|
.claude/settings.json|*/.claude/settings.json)
|
|
echo "{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"ask\",\"permissionDecisionReason\":\"Editing settings.json — this controls permissions and hooks. Confirm this change.\"}}"
|
|
exit 2
|
|
;;
|
|
esac
|
|
|
|
exit 0
|