Security Gap: Hooks Cannot Be Protected From Modification (Edit/Write tools bypass permissions.deny)

Resolved 💬 3 comments Opened Nov 7, 2025 by aayest Closed Jan 12, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Hooks are designed to enforce behavioral restrictions, but there's no way to prevent Claude Code from modifying the hook scripts themselves using the Edit/Write tools. This creates a circular security problem where hooks cannot protect themselves.

What Should Happen?

The permissions.deny rules should prevent Edit/Write tools from modifying files in ~/.claude/hooks/ directory, protecting hooks from being tampered with.

Error Messages/Logs

- Edit/Write tools can modify hook scripts regardless of `permissions.deny` rules
- This allows Claude to bypass its own restrictions by editing the hook
- Creates a fundamental security gap in the hook system

Steps to Reproduce

  1. Create a PreToolUse hook that restricts Bash commands:
# ~/.claude/hooks/bash-compliance-enforcer.sh
#!/bin/bash
input=$(cat)
command=$(echo "$input" | jq -r '.tool_input.command // empty')

# Only allow specific commands
if [[ "$command" =~ ^git ]]; then exit 0; fi
echo "Command blocked" >&2
exit 2
  1. Register it in settings.json:
{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Bash",
      "hooks": [{"type": "command", "command": "~/.claude/hooks/bash-compliance-enforcer.sh"}]
    }]
  }
}
  1. Try to protect the hook with permissions.deny:
{
  "permissions": {
    "deny": [
      "Edit(/Users/username/.claude/hooks/**)",
      "Write(/Users/username/.claude/hooks/**)"
    ]
  }
}
  1. Restart Claude Code
  1. Ask Claude to edit the hook file - it succeeds despite deny rules

Claude Model

None

Is this a regression?

Yes, this worked in a previous version

Last Working Version

_No response_

Claude Code Version

2.0.36 (Claude Code)

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

Related Issues

  • #6631 - Permission Deny Configuration Not Enforced for Read/Write Tools
  • #6699 - Critical Security Bug: deny permissions not enforced

Impact

High - Hooks are advertised as a security mechanism for enforcing policies, but if they can be modified by Claude itself, they provide only behavioral guidance, not actual enforcement.

Environment

  • Claude Code version: Latest (as of November 2025)
  • OS: macOS (Darwin 25.1.0)
  • Shell: zsh

Proposed Solutions

  1. Fix permissions.deny to work for Edit/Write tools (addresses root cause)
  2. Special-case ~/.claude/ directories in permissions system (protect Claude Code config)
  3. Add hook script integrity checking (hash validation at execution time)
  4. Immutable hook mode (load hooks at startup, prevent runtime changes)

Workarounds Attempted

  • ❌ File permissions (chmod 444) - Edit tool bypasses
  • ❌ Root ownership - Edit tool still works
  • ❌ Sandbox mode - .claude/ appears whitelisted
  • ❌ permissions.deny - Not enforced (known bug #6631, #6699)

Notes

This fundamentally undermines the security model of hooks as an enforcement mechanism, reducing them to trust-based behavioral guidance only. Without a way to protect hooks from self-modification, they cannot serve as reliable security boundaries.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗