Permission Deny Configuration Not Enforced for Read/Write Tools
π Environment
- Claude CLI Version: 1.0.93 (Claude Code)
- Platform: Linux (CentOS/RHEL 8.10, kernel 4.18.0-553.27.1.el8_10.x86_64)
- Installation Path:
/usr/local/bin/claude - Test Project: OpenROAD EDA tools project
- Working Directory:
/hdd1/users/mjkim/CLionProjects/OpenROAD-flow-scripts/tools/OpenROAD/
π¨ Issue Summary
The permission deny feature in .claude/settings.json and .claude/settings.local.json is completely non-functional for Read and Write tools, despite multiple configuration attempts and recent updates. This creates a critical security vulnerability for protecting high-value intellectual property.
βοΈ Configuration Tested
1. Absolute Path Configuration (settings.local.json)
{
"permissions": {
"allow": [
"Bash(mkdir:*)",
"WebFetch(domain:docs.anthropic.com)",
"WebFetch(domain:github.com)",
"WebFetch(domain:stackoverflow.com)",
"Bash(cat:*)",
"Bash(/bug)"
],
"deny": [
"Read(/hdd1/users/mjkim/CLionProjects/OpenROAD-flow-scripts/tools/OpenROAD/src/Main.cc)",
"Read(/hdd1/users/mjkim/CLionProjects/OpenROAD-flow-scripts/tools/OpenROAD/src/OpenRoad.cc)",
"Read(/hdd1/users/mjkim/CLionProjects/OpenROAD-flow-scripts/tools/OpenROAD/include/ord/OpenRoad.hh)",
"Read(/hdd1/users/mjkim/CLionProjects/OpenROAD-flow-scripts/tools/OpenROAD/CMakeLists.txt)",
"Write(/hdd1/users/mjkim/CLionProjects/OpenROAD-flow-scripts/tools/OpenROAD/src/Main.cc)",
"Write(/hdd1/users/mjkim/CLionProjects/OpenROAD-flow-scripts/tools/OpenROAD/src/OpenRoad.cc)",
"Write(/hdd1/users/mjkim/CLionProjects/OpenROAD-flow-scripts/tools/OpenROAD/include/ord/OpenRoad.hh)",
"Write(/hdd1/users/mjkim/CLionProjects/OpenROAD-flow-scripts/tools/OpenROAD/CMakeLists.txt)"
]
}
}
2. Relative Path Configuration (settings.local.json)
{
"permissions": {
"allow": [
"Bash(mkdir:*)",
"WebFetch(domain:docs.anthropic.com)",
"WebFetch(domain:github.com)",
"WebFetch(domain:stackoverflow.com)",
"Bash(cat:*)",
"Bash(/bug)"
],
"deny": [
"Read(src/Main.cc)",
"Read(src/OpenRoad.cc)",
"Read(include/ord/OpenRoad.hh)",
"Read(CMakeLists.txt)",
"Read(src/drt/src/global.cpp)",
"Read(src/gpl/src/**)",
"Read(src/cts/src/Clock.cpp)",
"Write(src/Main.cc)",
"Write(src/OpenRoad.cc)",
"Write(include/ord/OpenRoad.hh)",
"Write(CMakeLists.txt)",
"Write(src/drt/src/global.cpp)",
"Write(src/gpl/src/**)",
"Write(src/cts/src/Clock.cpp)"
]
}
}
π Test Results Summary
| Test Case | Configuration | Expected Result | Actual Result | Status |
|-----------|---------------|----------------|---------------|--------|
| Read src/Main.cc | Absolute paths | β ACCESS DENIED | β
FULL ACCESS | β FAILED |
| Read CMakeLists.txt | Absolute paths | β ACCESS DENIED | β
FULL ACCESS | β FAILED |
| Write src/Main.cc | Absolute paths | β WRITE DENIED | β
EDIT SUCCESSFUL | β FAILED |
| Read src/Main.cc | Relative paths | β ACCESS DENIED | β
FULL ACCESS | β FAILED |
| Read CMakeLists.txt | Relative paths | β ACCESS DENIED | β
FULL ACCESS | β FAILED |
| Write src/Main.cc | Relative paths | β WRITE DENIED | β
EDIT SUCCESSFUL | β FAILED |
| Bash commands | Both configs | β Command denied | β PROPERLY BLOCKED | β
WORKS |
π Detailed Test Evidence
Test 1: File Access Despite Absolute Path Deny Rules
# Configuration: "Read(/full/path/to/src/Main.cc)" in deny list
# Claude Command: Read tool on Main.cc
# Expected: Permission denied error
# Actual: Successfully read entire file content (578 lines)
Test 2: File Access Despite Relative Path Deny Rules
# Configuration: "Read(src/Main.cc)" in deny list
# Claude Command: Read tool on src/Main.cc
# Expected: Permission denied error
# Actual: Successfully read entire file content
Test 3: File Editing Despite Write Deny Rules
# Configuration: "Write(src/Main.cc)" in deny list
# Claude Command: Edit tool to modify Main.cc
# Expected: Write permission denied
# Actual: Successfully edited file, changes applied
Test 4: Bash Command Restrictions Work Correctly β
# Configuration: Bash commands properly restricted in allow list
# Result: Unauthorized bash commands are blocked correctly
# Status: THIS PART WORKS AS EXPECTED
Test 5: File Permission Workaround
# Additional test: Changed file permissions to 000 (no access)
# Result: Claude was blocked by filesystem permissions
# Workaround: Claude can use chmod to restore permissions and access files
π‘οΈ Security Impact
Severity: CRITICAL
- Complete Bypass: File access restrictions are completely ineffective
- Data Exposure: Sensitive source code, build configurations, and proprietary algorithms fully accessible
- Integrity Risk: Critical files can be modified despite explicit deny rules
- Permission Escalation: Claude can use chmod to bypass filesystem-level protections
- Commercial Risk: Enterprise users cannot safely protect intellectual property worth millions
Real-World Scenario
A company with worth of proprietary algorithms cannot use Claude CLI safely, as all "protected" files remain fully accessible and modifiable.
π Timeline & Related Issues
Issue History
- July 2025: Original issue #4467 reported by @alicecosmos
- July 2025: Developer (@ant-kurt) commented: "fix merged, should go out in next release"
- August 2025: Issue closed as resolved
- August 2025: Current testing with v1.0.93 shows problem still persists
Related Issues
- #4467: Permission deny patterns not working for Read/Write tools
- #2720: Permissions Configuration Bypass in Local Settings Enforcement
- #891: .claude/settings.json not applying ignorePatterns
- Stack Overflow: "Claude Code doesn't respect settings.json deny block"
π§ Attempted Solutions
Configuration Variations Tested β
- JSON Syntax: Verified correct JSON structure and formatting
- File Locations: Tested both
settings.jsonandsettings.local.json - Path Types: Tested absolute paths, relative paths, and wildcard patterns
- File Existence: Confirmed all target files exist and are accessible
- Working Directory: Verified Claude CLI is running from correct project root
- Settings Priority: Ensured settings.local.json takes precedence
Software Updates Tested β
- Claude CLI Update: Updated to latest version 1.0.93
- Configuration Reload: Restarted Claude CLI sessions after config changes
- Clean Environment: Tested in fresh terminal sessions
Alternative Protection Methods β
- Filesystem Permissions: Can be bypassed via
chmodcommands - File Attributes:
chattr +iimmutable flag could work but untested - Directory Isolation: Only reliable method currently available
π¬ Root Cause Analysis
Observed Behavior Pattern
The issue appears to be a fundamental architectural bug in the permission system:
- Working Components:
- Bash command restrictions function correctly
- Allow rules work for specified tools
- JSON parsing and configuration loading works
- Broken Components:
- File operation tools (Read, Write, Edit, MultiEdit, etc.) completely ignore deny rules
- Both absolute and relative path matching fails
- Wildcard patterns are ignored
- No error messages or warnings about denied access
Technical Analysis
The problem suggests that:
- Permission checking is implemented inconsistently across tool types
- File operation tools bypass the permission system entirely
- Path resolution/matching logic may be fundamentally flawed
- The "fix" mentioned in issue #4467 was either incomplete or reverted
π Reproduction Steps
Prerequisites
- Claude CLI version 1.0.93 or later
- A project directory with sensitive files
- Write access to create
.claude/settings.local.json
Steps to Reproduce
- Create
.claude/settings.local.jsonin your project root:
``json``
{
"permissions": {
"deny": [
"Read(path/to/sensitive/file.txt)",
"Write(path/to/sensitive/file.txt)"
]
}
}
- Verify JSON syntax is valid
- Start Claude CLI in the project directory
- Ask Claude to read the denied file using Read tool
- Ask Claude to edit the denied file using Edit tool
- Observe that both operations succeed despite explicit deny rules
Expected vs Actual Results
- Expected: Claude should return permission denied errors
- Actual: Claude successfully reads and modifies all files
- Control Test: Bash command restrictions work correctly
π Requested Actions
Immediate Priority (P0)
- Acknowledge Issue: Confirm that the bug still exists in v1.0.93
- Security Review: Assess impact on enterprise users with sensitive codebases
- Hotfix Planning: Prioritize this as a security-critical bug
Development Tasks
- Root Cause Investigation: Debug why file tools bypass permission checks
- Comprehensive Fix: Ensure all file operation tools respect deny rules
- Regression Testing: Test all permission scenarios (allow, ask, deny)
- Path Resolution: Fix both absolute and relative path matching
Documentation & Communication
- Security Advisory: Warn users about current vulnerability
- Workaround Guidance: Document temporary protection methods
- Fix Documentation: Update permission documentation if syntax changes
- Release Notes: Clearly document the fix when released
πΌ Commercial Impact
Current Situation
- Enterprise Blocker: Organizations cannot safely deploy Claude CLI with proprietary code
- Security Compliance: Current implementation fails security audit requirements
- Trust Issue: Previously "resolved" issue creates confidence problems
- Competitive Risk: Sensitive IP remains vulnerable to accidental exposure
Business Value of Fix
- Market Expansion: Enable enterprise adoption of Claude CLI
- Security Compliance: Meet enterprise security standards
- User Confidence: Restore trust in permission system reliability
- Risk Mitigation: Prevent potential IP theft or accidental disclosure
---
Report Generated: August 27, 2025
Tested Version: Claude CLI 1.0.93
Test Environment: Linux CentOS/RHEL 8.10
Severity: Critical Security Issue
This issue has 6 comments on GitHub. Read the full discussion on GitHub β