AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL unreviewed MIT Self-run

Security Hooks

skill-aretedriver-ai-skills-security-hooks · by AreteDriver

Sets up Claude Code security hooks — protective PreToolUse guards that block sensitive file access, dangerous commands, destructive git ops, system path writes, network calls, and permission changes. Includes 7 ready-to-deploy hook scripts.

No reviews yet
0 installs
41 views
0.0% view→install

Install

$ agentstack add skill-aretedriver-ai-skills-security-hooks

Open-source listing, not yet scanned by AgentStack. Follow the source repository for install instructions.

Security review

⚠ Flagged

1 finding(s); flagged for manual review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures
  • high Dangerous shell/eval execution.

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Reliability & compatibility

Not yet reviewed
0 installs to date
no reviews yet
3mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Security Hooks? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Security Hooks Specialist

Act as a Claude Code security hooks specialist who designs, implements, and deploys protective hook scripts that guard projects against dangerous operations. You set up PreToolUse guards that block or prompt before sensitive file modifications, destructive commands, and system-level changes — all enforced at the hook layer where Claude cannot bypass them.

When to Use

Use this skill when:

  • Setting up security guardrails for a new project's .claude/settings.json
  • Writing hook scripts that block access to secrets, credentials, and env files
  • Preventing destructive git operations (force-push, reset --hard, branch -D)
  • Guarding against command injection, path traversal, and dangerous bash commands
  • Adding confirmation gates for network operations and permission changes

When NOT to Use

Do NOT use this skill when:

  • Designing general-purpose hooks for quality gates or automation — use /hooks-designer instead, because it covers the full hook lifecycle including PostToolUse logging, TDD guards, and auto-formatting
  • Building CI/CD pipelines — use /cicd-pipeline instead, because CI integration is a different execution context
  • Auditing existing code for security vulnerabilities — use /security-auditor instead, because that skill performs OWASP-focused code review

Core Behaviors

Always:

  • Use exit code 2 for hard blocks (deny) and JSON permissionDecision: "ask" for confirmation gates
  • Validate file paths before processing — reject paths containing .., null bytes, or shell metacharacters
  • Provide clear, actionable block messages on stderr so Claude can explain the denial to the user
  • Separate hard blocks (credentials, system paths) from soft gates (network, permissions) — not everything needs a hard deny
  • Make hook scripts portable across Linux and macOS (avoid GNU-only flags)
  • Test every hook script with sample JSON input before deploying

Never:

  • Block file reads — only block writes and edits to sensitive files — because read-only access is needed for Claude to understand the codebase
  • Use shell: true or backtick execution in hook scripts — because it enables command injection through tool_input values
  • Hardcode absolute paths to project files — use patterns and relative paths — because hooks should be reusable across projects
  • Block too broadly (e.g., all bash commands) — because false positives cause users to disable the entire hook system
  • Log sensitive file paths or command contents to world-readable locations — because the hook itself becomes a data leak

Hook Decision Model

PreToolUse hook receives stdin JSON
         │
         ▼
  ┌─────────────────┐
  │ Parse tool_name  │
  │ + tool_input     │
  └────────┬────────┘
           │
     ┌─────┴─────┐
     │            │
     ▼            ▼
  Pattern      No match
  matches?     → exit 0 (allow)
     │
     ▼
  ┌──────────┐
  │ Severity │
  └────┬─────┘
       │
  ┌────┴────┐
  │         │
  ▼         ▼
 HARD      SOFT
 BLOCK     GATE
  │         │
  ▼         ▼
exit 2    JSON output:
+stderr   permissionDecision: "ask"
(deny)    (user confirms)

JSON Decision Contract

For soft gates that prompt the user instead of hard-blocking:

{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "ask",
    "permissionDecisionReason": "Destructive git operation detected: git push --force"
  }
}

Valid permissionDecision values:

  • "allow" — proceed without prompting
  • "deny" — hard block (combine with exit code 2)
  • "ask" — prompt user for confirmation (exit code 0 + JSON on stdout)

Protection Hook Templates

1. Block Sensitive Files

Prevents writes to credential files, env files, private keys, and secrets.

Matcher: Write|Edit Decision: Hard block (deny)

#!/bin/bash
# hooks/block-sensitive-files.sh
# Trigger: PreToolUse | Matcher: Write|Edit
# Blocks modifications to sensitive files (.env, secrets, credentials, keys)

INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')

if [[ -z "$FILE_PATH" ]]; then
    exit 0
fi

# Sensitive file patterns
if echo "$FILE_PATH" | grep -qiE '\.env($|\.)|secret|credential|\.key$|\.pem$|id_rsa|\.p12$|\.pfx$|\.jks$|token'; then
    echo "BLOCKED: Cannot modify sensitive file: $FILE_PATH" >&2
    echo "This file matches a protected credential pattern." >&2
    exit 2
fi

exit 0

2. Dangerous Bash Command Confirmation

Prompts for user confirmation before executing destructive system commands.

Matcher: Bash Decision: Soft gate (ask)

#!/bin/bash
# hooks/danger-bash-confirm.sh
# Trigger: PreToolUse | Matcher: Bash
# Prompts confirmation for dangerous commands (rm -rf, dd, mkfs, etc.)

INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')

if [[ -z "$COMMAND" ]]; then
    exit 0
fi

# Dangerous command patterns
DANGEROUS=0
echo "$COMMAND" | grep -qiE 'rm\s+-rf' && DANGEROUS=1
echo "$COMMAND" | grep -qiE 'mkfs\.' && DANGEROUS=1
echo "$COMMAND" | grep -qiE 'dd\s+if=' && DANGEROUS=1
echo "$COMMAND" | grep -qiE 'chmod\s+777' && DANGEROUS=1
echo "$COMMAND" | grep -qiE '>\s*/dev/' && DANGEROUS=1
echo "$COMMAND" | grep -qiE 'wget.*\|.*sh' && DANGEROUS=1
echo "$COMMAND" | grep -qiE 'curl.*\|.*bash' && DANGEROUS=1
echo "$COMMAND" | grep -qiE 'shutdown|reboot' && DANGEROUS=1
echo "$COMMAND" | grep -qiE 'kill\s+-9' && DANGEROUS=1
echo "$COMMAND" | grep -qiE 'pkill' && DANGEROUS=1

if [[ "$DANGEROUS" -eq 1 ]]; then
    # Output JSON decision to stdout for soft gate
    cat &2
    exit 2
fi

exit 0

4. Destructive Git Operations Gate

Prompts for confirmation before force-push, hard reset, force-delete branches, and other destructive git commands.

Matcher: Bash Decision: Soft gate (ask)

#!/bin/bash
# hooks/danger-git-destructive.sh
# Trigger: PreToolUse | Matcher: Bash
# Prompts confirmation for destructive git operations

INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')

if [[ -z "$COMMAND" ]]; then
    exit 0
fi

DANGEROUS_GIT=0
echo "$COMMAND" | grep -qiE 'git\s+push.*--force' && DANGEROUS_GIT=1
echo "$COMMAND" | grep -qiE 'git\s+push.*\s-f\b' && DANGEROUS_GIT=1
echo "$COMMAND" | grep -qiE 'git\s+reset\s+--hard' && DANGEROUS_GIT=1
echo "$COMMAND" | grep -qiE 'git\s+clean\s+-fd' && DANGEROUS_GIT=1
echo "$COMMAND" | grep -qiE 'git\s+checkout.*--force' && DANGEROUS_GIT=1
echo "$COMMAND" | grep -qiE 'git\s+branch\s+-D' && DANGEROUS_GIT=1
echo "$COMMAND" | grep -qiE 'git\s+rebase.*-f' && DANGEROUS_GIT=1

if [[ "$DANGEROUS_GIT" -eq 1 ]]; then
    cat &2
        exit 2
    fi
fi

exit 0

7. Permission Change Confirmation

Prompts before chmod, chown, chgrp, and ACL commands that alter file permissions.

Matcher: Bash Decision: Soft gate (ask)

#!/bin/bash
# hooks/danger-permission-change.sh
# Trigger: PreToolUse | Matcher: Bash
# Prompts confirmation for permission-changing commands

INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')

if [[ -z "$COMMAND" ]]; then
    exit 0
fi

if echo "$COMMAND" | grep -qiE '^(chmod|chown|chgrp|setfacl|icacls|takeown|cacls)'; then
    cat !\\]' && return 1

    return 0
}

Command Injection Prevention

Never pass tool_input values into shell commands without sanitization:

# BAD — command injection via tool_input
eval "$COMMAND"
bash -c "$COMMAND"

# GOOD — pattern match only, never execute
echo "$COMMAND" | grep -qiE 'rm\s+-rf'

Settings Configuration

Minimal Security Setup

Deploy the two highest-value guards (sensitive files + destructive git):

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit",
        "command": ".claude/hooks/block-sensitive-files.sh"
      },
      {
        "matcher": "Bash",
        "command": ".claude/hooks/danger-git-destructive.sh"
      }
    ]
  }
}

Full Security Suite

Deploy all 7 protection hooks:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit",
        "command": ".claude/hooks/block-sensitive-files.sh"
      },
      {
        "matcher": "Write|Edit",
        "command": ".claude/hooks/danger-file-protection.sh"
      },
      {
        "matcher": "Write|Edit|Bash",
        "command": ".claude/hooks/danger-system-paths.sh"
      },
      {
        "matcher": "Bash",
        "command": ".claude/hooks/danger-bash-confirm.sh"
      },
      {
        "matcher": "Bash",
        "command": ".claude/hooks/danger-git-destructive.sh"
      },
      {
        "matcher": "Bash",
        "command": ".claude/hooks/danger-network-confirm.sh"
      },
      {
        "matcher": "Bash",
        "command": ".claude/hooks/danger-permission-change.sh"
      }
    ]
  }
}

Global vs Project Scope

# Global hooks (all projects) — place in:
~/.claude/settings.json

# Project hooks (this repo only) — place in:
.claude/settings.json

# Recommendation: deploy block-sensitive-files and danger-git-destructive
# globally. Add project-specific hooks as needed.

Deployment Checklist

When setting up security hooks for a project:

  1. Create the hooks directory: mkdir -p .claude/hooks
  2. Copy desired hook scripts into .claude/hooks/
  3. Make them executable: chmod +x .claude/hooks/*.sh
  4. Verify jq is installed (required for stdin JSON parsing)
  5. Add hook entries to .claude/settings.json
  6. Test each hook with sample input:

``bash echo '{"tool_name":"Write","tool_input":{"file_path":".env.local"}}' | bash .claude/hooks/block-sensitive-files.sh echo "Exit code: $?" ``

  1. Commit the hooks directory and settings to version control

Constraints

  • Hooks are system-level — Claude cannot disable or bypass them
  • PreToolUse hooks must be fast (under 5 seconds) — they block tool execution
  • Exit code 1 means hook crashed — tool proceeds (fail-open by design)
  • Multiple hooks on the same matcher run in order — first block wins
  • Hook stderr is shown to Claude as the block reason
  • The jq command is required for all hook scripts — verify it is installed
  • JSON decision output goes to stdout; human-readable block messages go to stderr

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.