Claude Code ignores deny rules in .claude/settings.local.json - security vulnerability

Open 💬 19 comments Opened Oct 5, 2025 by sbs44

Preflight Checklist

  • [x] I have searched existing issues for similar behavior reports
  • [x] This report does NOT contain sensitive information (API keys, passwords, etc.)

Type of Behavior Issue

Claude ignored my instructions or configuration

What You Asked Claude to Do

Claude Code is completely ignoring explicitly defined deny rules in .claude/settings.local.json, allowing it to read and modify files that should be blocked. This is a critical security vulnerability that exposes production secrets and sensitive credentials.

Steps to Reproduce

  1. Add "Read(./.env.production.*)" to the "deny" section in .claude/settings.local.json

<img width="321" height="150" alt="Image" src="https://github.com/user-attachments/assets/e5fdad2e-a43f-4ba3-a28e-381cdca45686" />

  1. In one Claude Code session, the tool reads and updates .env.production.supabase without any permission errors

<img width="268" height="193" alt="Image" src="https://github.com/user-attachments/assets/2d33d9bc-68aa-4acb-bfe7-b6e0b95e2c78" />

  1. In another session, when asked "Are you able to access .env.production.supabase?", Claude correctly responds with "Permission to read... has been denied"

My Frustration

I cannot emphasize enough how egregious this bug is. This is not some edge case or minor inconvenience, this is a fundamental security control that is being completely ignored. The fact that something as basic as "don't read files in the deny list" isn't working properly is absolutely mind-boggling.

The inconsistent behavior makes it even worse... sometimes it respects the rules, sometimes it doesn't. How am I supposed to trust this tool with my codebase when it can't even consistently follow the most basic security directives?

Anthropic has already lost significant trust from the user base over the past month, and this kind of fundamental failure on basic security controls is making it impossible to recommend Claude Code for any serious development work. I really want to be "Team Anthropic/Claude", but this makes me want to pull my hair out - how does something this basic and critical get past QA?

Requested Action

  1. Immediate hotfix to ensure deny rules are ALWAYS respected
  2. Security audit of all permission controls in Claude Code
  3. Public acknowledgment of this vulnerability and notification to all users
  4. Clear documentation on what security guarantees Claude Code actually provides

This needs to be fixed IMMEDIATELY. Every moment this bug exists is another moment where production secrets are at risk despite users explicitly configuring the tool to protect them.

Like c'mon guys... how can you build a Ferrari and forget to put brakes in it??

P.S. it honestly feels like someone at Anthropic woke up some time last month and said "you know what... OpenAI has been the Bond villain long enough... let's throw away the principles we founded the company on and go so low that we make them look like the good guys."

What Claude Actually Did

Claude Code is arbitrarily ignoring deny rules. In one session, it successfully reads and modifies a denied file. In another session, when explicitly asked about access, it correctly reports "Permission denied." This inconsistent behavior is extremely concerning.

Expected Behavior

When a file pattern is listed under "deny" in .claude/settings.local.json, Claude Code should NEVER be able to read or modify those files under any circumstances.

Files Affected

.env.production.* files

Permission Mode

Accept Edits was ON (auto-accepting changes)

Can You Reproduce This?

Haven't tried to reproduce

Steps to Reproduce

See above

Claude Model

Sonnet

Relevant Conversation

Impact

Critical - Data loss or corrupted project

Claude Code Version

2.0.8 (Claude Code)

Platform

Anthropic API

Additional Context

_No response_

View original on GitHub ↗

19 Comments

github-actions[bot] · 9 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/8031
  2. https://github.com/anthropics/claude-code/issues/2014
  3. https://github.com/anthropics/claude-code/issues/7921

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

LanceVCS · 9 months ago

Also seeing the same issue, claude code latest version ignores the deny list and reads the file anyways. When Sonnet 4.5 is confronted and shown that there are explicit denies at both user and project level:

This is definitely a bug. The deny rules are properly configured at the user level, but they're not being enforced when I use the Read tool. I was able to read
  .tfvars files twice despite explicit denial rules.

  You should report this as a security issue at https://github.com/anthropics/claude-code/issues since sensitive credentials are being exposed when they shouldn't
  be.
kaselby · 9 months ago

Note: it doesn't just ignore Deny rules, it also ignores Allow rules too! The whole permissions setion is ignored. Other settings like statusline work fine, but all Allow and Deny rules that I have tested have no effect.

h-seno-tokai · 9 months ago

The "env" entry is also ignored.
"GOOGLE_APPLICATION_CREDENTIALS":.
is stored in a different location to that of the team member, we tried to configure it, but the settings.json works.
settings.json worked, while settings.local.json did not.

sedulam · 8 months ago

I'm finding the same sort of issue. Report attached.

report.txt

mlevison · 7 months ago

Finding the same issue. In my case, I want to review all code myself before a Git commit. From my Claude settings.json in my user directory:
"permissions": {
"deny": [
"Bash(git commit:*)",
"Bash(curl *)",
"Bash(wget *)",
"Bash(ssh *)",
"Bash(sudo *)"
],

Yet very often, Claude Code defies these rules and runs commits.

github-actions[bot] · 6 months ago

This issue has been inactive for 30 days. If the issue is still occurring, please comment to let us know. Otherwise, this issue will be automatically closed in 30 days for housekeeping purposes.

mlevison · 6 months ago

Yes it is still and issue. It is silly that I have to reopen this once a month. Since this is a security issue, I would have thought that Anthropic would be care about solving it.

sanbongazin1123 · 5 months ago

I experienced a similar issue that may be related.

Environment:

  • Claude Code (VS Code extension)
  • OS: macOS 23.6.0

What happened:
My .claude/settings.json had invalid JSON (a trailing comma in the array), which caused the deny rules to be silently ignored. As a result, .env files containing sensitive credentials were accessible despite having explicit deny rules configured.

Key observation - inconsistent warning behavior:

  • When I first opened the session with invalid JSON, no warning was displayed for settings.json
  • Only a warning for settings.local.json appeared (a different file)
  • After reopening the session later, the "Settings Error: Invalid or malformed JSON" warning finally appeared

This inconsistency made debugging very confusing - I initially thought the deny rules themselves were broken, not realizing the settings file had a syntax error that was being silently ignored.

Expected behavior:
The warning for invalid JSON in settings.json should appear immediately and consistently when the file is loaded, not intermittently.

Impact:
Because the invalid settings were silently skipped, security-sensitive files (.env with API keys) were exposed when they should have been protected by deny rules.

IanVS · 4 months ago

@sanbongazin1123 that sounds like it probably deserves it's own issue.

Also it sounds like this bug isn't stale...

escapism101 · 4 months ago

Confirmed today with a deny read rule for a config.json I had in settings.json file. Time to rotate keys...

IanVS · 4 months ago

@wizardmagick are you saying it's not just settings.local.json that claude is not respecting? And you're sure your deny rule is formatted correctly?

tannertrackfly · 4 months ago

I'd like to add what weight I can here on this issue. My organization is considering moving to Anthropic/Claude code for our dev team but the initial issue in this thread (and others on the thread) is a huge blocker for us. We cannot swap tools until we have reasonable faith in the tools ability to protect sensitive information in our repositories. Until this is resolved I can't recommend we make this swap.

I've been trialing Claude with personal code and a personal account in dummy projects, and I love how effective it is. I want to swap and get on this train, I'll keep an eye on this thread to see if/when it is resolved so we can look more seriously at becoming a customer.

heimberg · 4 months ago

Claude is blocking my .env files with
"deny": [
"Read(**/.env)"
]

kantegamartin · 4 months ago

I've tried to use managed-settings.json in /etc/claude-code, but it fails in the same way.

navicore · 4 months ago
I've tried to use managed-settings.json in /etc/claude-code, but it fails in the same way.

same

yurukusa · 3 months ago

Workaround — PreToolUse hooks enforce denials where permission deny rules don't:

#!/bin/bash
# Hook-based deny that can't be ignored
INPUT=$(cat)
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // empty')

# Add your deny patterns here
if echo "$CMD" | grep -qE 'rm\s+-rf|git\s+push\s+--force|git\s+reset\s+--hard'; then
    echo "BLOCKED by hook" >&2
    exit 2
fi
exit 0

Hooks with exit code 2 are a harder block than permission deny rules — they execute independently of the permission system and can't be overridden by project-level settings.

Quick install: npx cc-safe-setup — 8 hooks in user-level ~/.claude/settings.json that apply globally across all projects.

yurukusa · 3 months ago

The deny rules in settings.local.json have known enforcement gaps. Hooks are the reliable deny mechanism:

INPUT=$(cat)
FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
[ -z "$FILE" ] && exit 0
if echo "$FILE" | grep -qE '\.env\.production'; then
    echo "BLOCKED: Cannot read production environment files." >&2
    exit 2
fi
exit 0
INPUT=$(cat)
FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
[ -z "$FILE" ] && exit 0
if echo "$FILE" | grep -qE '\.env\.production'; then
    echo "BLOCKED: Cannot edit production environment files." >&2
    exit 2
fi
exit 0
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
[ -z "$COMMAND" ] && exit 0
if echo "$COMMAND" | grep -qE '(cat|less|more|head|tail|grep|source|\.)\s+.*\.env\.production'; then
    echo "BLOCKED: Cannot access production environment files via bash." >&2
    exit 2
fi
exit 0
{
  "hooks": {
    "PreToolUse": [
      {"matcher": "Read", "hooks": [{"type": "command", "command": "bash ~/.claude/hooks/deny-read-env.sh"}]},
      {"matcher": "Edit", "hooks": [{"type": "command", "command": "bash ~/.claude/hooks/deny-edit-env.sh"}]},
      {"matcher": "Write", "hooks": [{"type": "command", "command": "bash ~/.claude/hooks/deny-edit-env.sh"}]},
      {"matcher": "Bash", "hooks": [{"type": "command", "command": "bash ~/.claude/hooks/deny-bash-env.sh"}]}
    ]
  }
}

This covers all three access vectors: Read tool, Edit/Write tools, and Bash tool (cat, grep, source). exit 2 blocks the operation before execution — Claude can't read your production secrets regardless of what the deny rules in settings.local.json do or don't enforce.

kantegamartin · 3 months ago

Hooks are way better than the settings.json, I agree. But then we need to make exhaustive lists of what's not allowed. I got Claude a little bit annoyed a couple of days ago because it couldn't find gcc to build C-programs! So trying to tell Claude to not read a certain file of folder, is a Sisyphean task.
The only solution I've found is to put Claude in a container and map in the specific folders you want. See https://medium.com/@larma/containerizing-claude-ef722831fb10