Skip to content

Instantly share code, notes, and snippets.

@m-waqas88
Created March 24, 2026 15:06
Show Gist options
  • Select an option

  • Save m-waqas88/f796b95edc6bc3351defe56c25177a28 to your computer and use it in GitHub Desktop.

Select an option

Save m-waqas88/f796b95edc6bc3351defe56c25177a28 to your computer and use it in GitHub Desktop.
#!/bin/bash
# Claude Code safety hook — blocks dangerous commands
# Runs before every Bash tool call via PreToolUse hook
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // ""')
block() {
echo "BLOCKED: $1" >&2
exit 2
}
# ─── File Destruction ─────────────────────────────────────────────────────────
echo "$COMMAND" | grep -qE '(^|\s|;|\||&&)rm\s' && block "rm is not allowed"
echo "$COMMAND" | grep -qE '(^|\s|;|\||&&)shred\s' && block "shred is not allowed"
echo "$COMMAND" | grep -qE '(^|\s|;|\||&&)truncate\s+-s\s+0' && block "truncating files to zero not allowed"
echo "$COMMAND" | grep -qE '(^|\s|;|\||&&)dd\s+if=' && block "dd overwrite not allowed"
echo "$COMMAND" | grep -qE '(^|\s|;|\||&&)mv\s+(-f\s|.*-f$)' && block "force move not allowed"
# ─── Shell Script Execution ───────────────────────────────────────────────────
echo "$COMMAND" | grep -qE '(^|\s|;|\||&&)(bash|sh|zsh|source|\.)\s+\S+\.(sh|bash|zsh)' \
&& block "executing shell scripts not allowed"
# ─── Remote Code Execution ────────────────────────────────────────────────────
echo "$COMMAND" | grep -qE '(curl|wget).*\|\s*(ba)?sh' && block "piping remote content to shell not allowed"
echo "$COMMAND" | grep -qE '(^|\s|;|\||&&)eval\s' && block "eval not allowed"
# ─── Git: Destructive / History Rewrite ──────────────────────────────────────
echo "$COMMAND" | grep -qE 'git\s+merge\b' && block "git merge not allowed — merge manually"
echo "$COMMAND" | grep -qE 'git\s+rebase\b' && block "git rebase not allowed"
echo "$COMMAND" | grep -qE 'git\s+reset\s+--hard' && block "git reset --hard not allowed"
echo "$COMMAND" | grep -qE 'git\s+push\s+.*(--force|-f)\b' && block "git force push not allowed"
echo "$COMMAND" | grep -qE 'git\s+push\s+.*--force-with-lease' && block "git push --force-with-lease not allowed"
echo "$COMMAND" | grep -qE 'git\s+clean\s+.*-f' && block "git clean -f not allowed"
echo "$COMMAND" | grep -qE 'git\s+(checkout\s+\.|restore\s+\.)' && block "discarding all local changes not allowed"
echo "$COMMAND" | grep -qE 'git\s+branch\s+.*-D\b' && block "git branch force delete not allowed"
echo "$COMMAND" | grep -qE 'git\s+commit\s+.*--amend' && block "git commit --amend not allowed"
echo "$COMMAND" | grep -qE 'git\s+stash\s+drop' && block "git stash drop not allowed"
# ─── Git: Requires Manual Review ─────────────────────────────────────────────
if echo "$COMMAND" | grep -qE 'git\s+commit\b'; then
# Extract commit message from -m / --message flag (double or single quotes)
MSG=$(echo "$COMMAND" | grep -oE -- '-m\s+"[^"]+"' | sed 's/-m[[:space:]]*"//;s/"$//')
[ -z "$MSG" ] && MSG=$(echo "$COMMAND" | grep -oE -- "-m[[:space:]]+'[^']+'" | sed "s/-m[[:space:]]*'//;s/'$//")
[ -z "$MSG" ] && MSG=$(echo "$COMMAND" | grep -oE -- '--message\s+"[^"]+"' | sed 's/--message[[:space:]]*"//;s/"$//')
[ -z "$MSG" ] && MSG=$(echo "$COMMAND" | grep -oE -- "--message[[:space:]]+'[^']+'" | sed "s/--message[[:space:]]*'//;s/'$//")
[ -z "$MSG" ] && MSG="(no inline -m flag — editor will open)"
jq -n --arg msg "$MSG" --arg cmd "$COMMAND" '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "ask",
permissionDecisionReason: ("Commit message: \"" + $msg + "\"\n\nCommand: " + $cmd)
}
}'
exit 0
fi
echo "$COMMAND" | grep -qE 'git\s+push\b' && block "git push requires your review — push manually"
# ─── Publishing / Deploying ───────────────────────────────────────────────────
echo "$COMMAND" | grep -qE '(^|\s|;|\||&&)npm\s+publish\b' && block "npm publish not allowed"
echo "$COMMAND" | grep -qE '(^|\s|;|\||&&)cargo\s+publish\b' && block "cargo publish not allowed"
echo "$COMMAND" | grep -qE '(^|\s|;|\||&&)docker\s+push\b' && block "docker push not allowed"
# ─── Privilege Escalation ─────────────────────────────────────────────────────
echo "$COMMAND" | grep -qE '(^|\s|;|\||&&)sudo\s' && block "sudo not allowed"
# ─── System Power Commands ────────────────────────────────────────────────────
echo "$COMMAND" | grep -qE '(^|\s|;|\||&&)(shutdown|reboot|halt)\b' && block "system power commands not allowed"
# ─── Process Killing ──────────────────────────────────────────────────────────
echo "$COMMAND" | grep -qE '(^|\s|;|\||&&)kill\s+-9\b' && block "kill -9 not allowed"
echo "$COMMAND" | grep -qE '(^|\s|;|\||&&)(killall|pkill)\s' && block "killall/pkill not allowed"
# ─── Permission / Ownership Changes ──────────────────────────────────────────
echo "$COMMAND" | grep -qE '(^|\s|;|\||&&)chmod\s+.*-R' && block "recursive chmod not allowed"
echo "$COMMAND" | grep -qE '(^|\s|;|\||&&)chown\s+.*-R' && block "recursive chown not allowed"
# ─── Unreviewed Package Installs ─────────────────────────────────────────────
echo "$COMMAND" | grep -qE '(^|\s|;|\||&&)npm\s+(install|i)\s+.*-g\b' && block "global npm install not allowed — install manually after review"
echo "$COMMAND" | grep -qE '(^|\s|;|\||&&)pip\s+install\b' && block "pip install not allowed — install manually after review"
echo "$COMMAND" | grep -qE '(^|\s|;|\||&&)brew\s+install\b' && block "brew install not allowed — install manually after review"
# ─── Shell History & Cron ─────────────────────────────────────────────────────
echo "$COMMAND" | grep -qE '(^|\s|;|\||&&)history\s+-c\b' && block "clearing shell history not allowed"
echo "$COMMAND" | grep -qE '(^|\s|;|\||&&)crontab\s+-r\b' && block "crontab -r not allowed"
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment