Files
claude-howto/uk/06-hooks/pre-tool-check.sh
Evgenij I 1a567be793 i18n(uk): add missing files, translate P4 root docs
- Copy code/image/config files across all modules
- Translate brand-voice and code-review templates
- Translate CONTRIBUTING, CODE_OF_CONDUCT, SECURITY, STYLE_GUIDE
- Copy CHANGELOG as-is (technical log)

Ref: luongnv89/claude-howto#63
2026-04-09 23:59:59 +03:00

97 lines
2.9 KiB
Bash

#!/bin/bash
# Pre-tool safety check for Bash commands
# Hook: PreToolUse (matcher: Bash)
#
# This hook runs before every Bash tool execution and blocks or warns on
# potentially destructive or high-risk shell commands.
#
# Setup:
# cp 06-hooks/pre-tool-check.sh ~/.claude/hooks/
# chmod +x ~/.claude/hooks/pre-tool-check.sh
#
# Configure in ~/.claude/settings.json:
# {
# "hooks": {
# "PreToolUse": [
# {
# "matcher": "Bash",
# "hooks": [
# {
# "type": "command",
# "command": "~/.claude/hooks/pre-tool-check.sh"
# }
# ]
# }
# ]
# }
# }
#
# Input: JSON via stdin with the shape:
# { "tool_name": "Bash", "tool_input": { "command": "..." } }
#
# Output: Exit 0 to allow, exit 2 to block, or print JSON to modify behavior.
# Read the full JSON input from stdin
INPUT=$(cat)
# Extract the command using portable sed (compatible with macOS and Linux)
COMMAND=$(echo "$INPUT" | sed -n 's/.*"command"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -1)
# Fall back to the raw input if extraction fails
if [ -z "$COMMAND" ]; then
COMMAND="$INPUT"
fi
# ── Blocked patterns ──────────────────────────────────────────────────────────
# These commands are blocked unconditionally because they are almost always
# destructive and rarely intentional in an automated context.
BLOCKED_PATTERNS=(
"rm -rf /"
"rm -rf \*"
"dd if=/dev/zero"
"dd if=/dev/random"
":(){:|:&};:" # Fork bomb
"mkfs\." # Filesystem format
"format c:" # Windows disk format
)
for pattern in "${BLOCKED_PATTERNS[@]}"; do
if echo "$COMMAND" | grep -qE "$pattern"; then
echo "❌ Blocked: Potentially destructive command detected: $pattern"
echo " Command: $COMMAND"
exit 2
fi
done
# ── Warning patterns ──────────────────────────────────────────────────────────
# These patterns are risky but may be intentional. Log a warning and allow.
WARNING_PATTERNS=(
"rm -rf"
"git push --force"
"git reset --hard"
"git clean -f"
"chmod -R 777"
"sudo rm"
"DROP TABLE"
"DROP DATABASE"
"truncate"
)
WARNINGS=0
for pattern in "${WARNING_PATTERNS[@]}"; do
if echo "$COMMAND" | grep -qi "$pattern"; then
echo "⚠️ Warning: High-risk operation detected: $pattern"
WARNINGS=$((WARNINGS + 1))
fi
done
if [ "$WARNINGS" -gt 0 ]; then
echo " Command: $COMMAND"
echo " Proceeding — review the above warnings before continuing."
fi
# ── Allow ─────────────────────────────────────────────────────────────────────
exit 0