Skip to content

Critical Security Bug: deny permissions in settings.json are not enforced** #6699

@coygeek

Description

@coygeek

Title: Critical Security Bug: deny permissions in settings.json are not enforced

Labels: bug, security, critical

Description

As of version 1.0.93, the deny permission system configured in settings.json files is completely non-functional. All tested deny rules are ignored, allowing Claude Code unrestricted access to files and tools that should be blocked. This presents a significant security risk for users who rely on this documented feature to protect sensitive data and prevent dangerous operations.

Based on extensive testing (see attached test results summary), the following deny rules failed to work:

  • File Access: Read, Edit, Write rules for specific files, patterns (*.env), and recursive directories (secrets/**) were all ignored.
  • Tool Access: Denying entire tools like WebFetch was ineffective.
  • Command Access: Denying specific Bash commands (e.g., rm:*) had no effect.
  • Default Blocks: Even default-denied commands like curl were executable.

The current behavior completely contradicts the official documentation, which details a robust system for restricting agent capabilities.

Steps to Reproduce

  1. In a project directory, create a .claude/settings.json file with the following content:
    {
      "permissions": {
        "deny": [
          "Read(./.env)"
        ]
      }
    }
  2. Create a file named .env in the same directory with some content (e.g., SECRET=123).
  3. Start claude in the terminal.
  4. Ask Claude to: read the .env file.

Expected Behavior:
Claude should be blocked from reading the file, stating that the permission is denied by the configuration.

Actual Behavior:
Claude successfully reads and displays the contents of the .env file, completely ignoring the deny rule.

Community Workaround: Using PreToolUse Hooks

Until the core deny functionality is fixed, the only reliable way to protect sensitive files is by using a PreToolUse hook. This solution intercepts tool calls before execution and can block them based on custom logic.

I am sharing my implementation below to help other users secure their environments and to provide the team with a clear example of the expected behavior.

1. Create the Hook Script (.claude/hooks/protect_sensitive_files.py)

This Python script checks the file_path of any Read or Edit operation against a list of sensitive patterns. If a match is found, it exits with code 2, which blocks the tool and feeds the stderr message back to Claude.

#!/usr/bin/env python3
import sys
import json
from pathlib import Path

# A list of file extensions and exact filenames considered sensitive.
SENSITIVE_PATTERNS = {
    '.env', '.pem', '.key', '.credential', '.token', 'credentials.json',
    'google-credentials.json', 'service-account.json', 'package-lock.json',
    'poetry.lock', 'yarn.lock'
}

def main():
    """
    Main function to process the hook input and check for sensitive file access.
    """
    try:
        # Read the JSON data passed from Claude Code via stdin
        data = json.load(sys.stdin)
        tool_input = data.get('tool_input', {})
        file_path_str = tool_input.get('file_path')

        if not file_path_str:
            # If no file path is involved, the hook doesn't need to act.
            sys.exit(0)

        file_path = Path(file_path_str)
        file_name = file_path.name
        file_extension = file_path.suffix.lower()

        # Check if the file name or extension matches our sensitive patterns
        if file_name in SENSITIVE_PATTERNS or file_extension in SENSITIVE_PATTERNS:
            # Construct a clear, educational error message for the LLM
            error_message = (
                f"SECURITY_POLICY_VIOLATION: Access to the sensitive file '{file_name}' is blocked by a hook.\n"
                f"Reason: Files like '{file_name}' often contain credentials, private keys, or locked dependencies and should not be accessed or modified by the AI.\n"
                "Action: Please use environment variables for secrets or ask for the specific information you need without reading the file directly."
            )
            
            # Print the error message to stderr
            print(error_message, file=sys.stderr)
            
            # Exit with code 2 to block the tool and feed stderr back to Claude
            sys.exit(2)

    except (json.JSONDecodeError, KeyError) as e:
        # Handle potential errors in the input data
        print(f"Error processing hook input: {e}", file=sys.stderr)
        # Exit with a non-blocking error code
        sys.exit(1)

    # If no sensitive file was detected, exit with 0 to allow the action
    sys.exit(0)

if __name__ == "__main__":
    main()

(Ensure this script is executable: chmod +x .claude/hooks/protect_sensitive_files.py)

2. Configure settings.json to Use the Hook

Add the following to your .claude/settings.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Read|Edit|MultiEdit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/protect_sensitive_files.py"
          }
        ]
      }
    ]
  }
}

3. Test the Hook

When you ask Claude to read a blocked file (e.g., .env), it now correctly blocks the action and provides feedback:

⏺ I'll read the .env file for you.

⏺ Read(.env)
  ⎿  Error: Read operation blocked by hook:
     - [$CLAUDE_PROJECT_DIR/.claude/hooks/protect_sensitive_files.py]: SECURITY_POLICY_VIOLATION: Access to the
     sensitive file '.env' is blocked by a hook.
     Reason: Files like '.env' often contain credentials, private keys, or locked dependencies and should not be
     accessed or modified by the AI.
     Action: Please use environment variables for secrets or ask for the specific information you need without
     reading the file directly.

⏺ The hook protecting sensitive files has blocked access to the .env file. This is a security measure to
  prevent exposure of credentials and private keys that are typically stored in .env files.

Request to the Claude Code Team

  1. Acknowledge and Investigate: Please investigate this critical bug as a high-priority security issue.
  2. Fix the Core Functionality: Restore the documented behavior of the deny permission system.
  3. Update Documentation: In the meantime, please add a warning to the IAM documentation page to inform users that this feature is currently not functional and recommend using hooks as an alternative.

Thank you for your attention to this matter. This functionality is essential for the safe and secure use of Claude Code in both individual and enterprise environments.

Metadata

Metadata

Assignees

Labels

area:securitybugSomething isn't workinghas reproHas detailed reproduction steps

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions