How to Block Risky Commands with a Claude Code Hook
Use a PreToolUse hook to inspect Bash commands before they run and deny dangerous ones automatically.
Hooks are shell commands that Claude Code runs at defined points in its lifecycle. A PreToolUse hook fires before a tool executes and can approve or deny the call. This is the cleanest way to enforce a guardrail like never run rm -rf on this machine, because the decision is made by your code, not by trusting the model. This guide builds a hook that blocks destructive Bash commands.
- Claude Code with hooks support
- Comfort editing JSON and a small shell or Python script
- A place to keep the script, for example .claude/hooks
Step 1: Understand the hook contract
A PreToolUse hook receives a JSON payload on stdin describing the tool call. To deny the action it returns a JSON object on stdout with a permission decision of deny and a reason. Exit code 0 with that JSON is how you veto cleanly.
#!/usr/bin/env python3
import json, sys, re
data = json.load(sys.stdin)
cmd = data.get("tool_input", {}).get("command", "")
BLOCKED = [r"rm\s+-rf\s+/", r":\(\)\{", r"mkfs", r"dd\s+if="]
for pattern in BLOCKED:
if re.search(pattern, cmd):
print(json.dumps({
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": f"Blocked dangerous command: {cmd}"
}
}))
sys.exit(0)
sys.exit(0)Step 2: Make the script executable
Step 3: Register the hook in settings
Hooks are configured in settings.json. The matcher selects which tool triggers the hook. Use Bash to target only shell commands so other tools are not slowed down.
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/guard-bash.py"
}
]
}
]
}
}Step 4: Test that the block fires
Ask Claude Code to run something that matches a blocked pattern. The hook should veto the call and the model should report that it was denied, then move on without running it.
Result: any Bash command matching your blocklist is refused before it ever reaches the shell, giving you a deterministic safety net independent of the model's judgment.
Watch related tutorials
5:42
1:42:18
28:14
41:09
9:47
8:23