CR-2026-02-26: Claude Code Settings Credential Exposure
Change Summary
CR ID |
CR-2026-02-26-001 |
Date |
2026-02-26 |
Priority |
P0 - Emergency |
Type |
Security Remediation |
Systems |
modestus-razer workstation |
Status |
Completed (Rotation Pending) |
Executive Summary
EMERGENCY: Multiple credentials (BORG backup passphrase, ISE API tokens, pfSense API key, secrets manager wildcards) were exposed in Claude Code’s ~/.claude/settings.local.json auto-approve rules. Remediated by removing dangerous patterns and cleaning shell history.
Discovery
User requested security audit of Claude Code configuration. Scan revealed hardcoded credentials in allowed commands list:
grep -En 'PASSPHRASE=|_PASS=|_TOKEN=|API_KEY|dsec show|dsource|gopass show' \
~/.claude/settings.local.json
Exposed Credentials Summary
| Category | Pattern | Risk | Count |
|---|---|---|---|
BORG Backup |
|
Backup repository access |
4 |
ISE ERS API |
|
ISE admin access |
10+ |
ISE DataConnect |
|
ISE database access |
3 |
pfSense API |
|
Firewall admin access |
1 |
Secrets Wildcards |
|
Access to ALL secrets |
4 |
Decrypt Wildcard |
|
Decrypt any file |
1 |
Remediation
Phase 1: Remove Dangerous Patterns
Entries removed from settings.local.json:
# Secrets wildcards (allowed access to ANY secret)
Bash(dsec show:*)
Bash(dsource d000:*)
Bash(~/.secrets/bin/dsec:*)
Bash(~/.secrets/bin/decrypt-file:*)
# Hardcoded BORG password (4 entries)
Bash(export BORG_PASSPHRASE="<redacted>")
Bash(sudo BORG_PASSPHRASE="<redacted>" borg list:*)
# Hardcoded ISE tokens (10+ entries)
Bash(ISE_API_TOKEN="<base64>":*)
Bash(ISE_PAN_IP=... ISE_API_TOKEN="<base64>" uv run:*)
# Hardcoded ISE passwords
Bash(ISE_API_PASS="<plaintext>" uv run:*)
Bash(ISE_DC_PASS=<plaintext> timeout 10 uv run:*)
# Hardcoded pfSense API key
Bash(curl -ks -H 'X-API-Key: <hex>' ...)
# Specific dsec show paths
Bash(~/.secrets/bin/dsec show d000 dev/network)
Safe patterns retained:
# Variable references (not hardcoded values)
Bash(sudo BORG_PASSPHRASE="$BORG_PASSPHRASE" borg list:*)
# Tools that use dsource internally
Bash(netapi ise:*)
# Listing (not showing)
Bash(gopass ls:*)
Phase 2: Clean Shell History
# Discovery
grep -c '<password-pattern>' ~/.bash_history ~/.zsh_history
# /home/evanusmodestus/.bash_history:5
# /home/evanusmodestus/.zsh_history:2
# Remediation
grep -v '<password-pattern>' ~/.bash_history > /tmp/bash_clean && \
mv /tmp/bash_clean ~/.bash_history
grep -v '<password-pattern>' ~/.zsh_history > /tmp/zsh_clean && \
mv /tmp/zsh_clean ~/.zsh_history
# Verification
grep -c '<password-pattern>' ~/.bash_history ~/.zsh_history
# /home/evanusmodestus/.bash_history:0
# /home/evanusmodestus/.zsh_history:0
Phase 3: Final Verification
# Verify no dangerous patterns remain
grep -En 'PASSPHRASE=.*[^$]|_PASS=.*[^$]|_TOKEN=|API_KEY|dsec show|dsource d000|gopass show' \
~/.claude/settings.local.json
# Expected: Only variable references like $BORG_PASSPHRASE
CLI Mastery: Credential Detection
Grep Patterns for Secrets
# Generic credential patterns
grep -rn --include='*.json' --include='*.yaml' --include='*.yml' \
-E 'password|secret|token|api.?key|credential' ~/.config/
# Base64-encoded credentials (64+ chars of base64)
grep -rn -E '[A-Za-z0-9+/]{64,}={0,2}' ~/.config/
# Hex strings (API keys)
grep -rn -E '[0-9a-f]{32,}' ~/.config/
# Environment variable vs literal value
# SAFE: PASSWORD="$VAR"
# DANGER: PASSWORD="actualvalue"
grep -E 'PASSWORD="[^$]' ~/.config/
History Cleaning
# Prevent secrets from entering history
# Add to .bashrc/.zshrc:
export HISTCONTROL=ignorespace # Commands starting with space are ignored
# Clean specific pattern from history
grep -v '<pattern>' ~/.bash_history > /tmp/clean && mv /tmp/clean ~/.bash_history
# Clean multiple patterns
grep -vE 'pattern1|pattern2|pattern3' ~/.zsh_history > /tmp/clean && \
mv /tmp/clean ~/.zsh_history
# Secure delete (overwrite before delete)
shred -u ~/.bash_history && touch ~/.bash_history
Audit Claude Code Settings
# List all allowed commands
jq -r '.allowedCommands[]' ~/.claude/settings.local.json | sort -u
# Find commands with credentials
jq -r '.allowedCommands[]' ~/.claude/settings.local.json | \
grep -iE 'pass|token|key|secret'
# Count by pattern
jq -r '.allowedCommands[]' ~/.claude/settings.local.json | \
awk -F':' '{print $1}' | sort | uniq -c | sort -rn
Root Cause Analysis
Claude Code’s auto-approve system (settings.local.json) accumulated allowed commands over time without review. When commands with credentials were approved during interactive sessions, the full command including secrets was persisted.
Attack Vector
-
User approves command with hardcoded credential
-
Claude Code saves full command text to settings.local.json
-
File persists indefinitely without review
-
Wildcard patterns (
dsec:*) grant access to ALL secrets
Prevention Checklist
When Approving Commands
-
Never approve commands with literal credentials
-
Use
$VARreferences only (e.g.,$BORG_PASSPHRASE) -
Never approve
dsec show:*ordsource:*wildcards -
Never approve
gopass show:*wildcards -
Never approve decrypt wildcards
Periodic Review
-
Monthly audit of
~/.claude/settings.local.json -
Search for PASSPHRASE=, TOKEN=, API_KEY patterns
-
Remove any entries with hardcoded values
-
Verify shell history doesn’t contain secrets
Shell Configuration
# Add to .bashrc/.zshrc
export HISTCONTROL=ignorespace
export HISTIGNORE="*PASSPHRASE*:*TOKEN*:*PASSWORD*:dsec*:gopass show*"
Pending Actions
| Priority | Action | Status |
|---|---|---|
P0 |
Rotate BORG backup passphrase |
PENDING |
P1 |
Rotate ISE ERS API credentials |
PENDING |
P1 |
Rotate pfSense API key |
PENDING |
P2 |
Rotate ISE DataConnect password |
PENDING |
P2 |
Audit other workstations |
PENDING |
Key Lessons
| Issue | Mitigation |
|---|---|
Auto-approve persists full command text |
Only approve commands with |
Wildcards grant excessive access |
Never allow |
Shell history contains secrets |
Use |
No periodic config review |
Add monthly review to maintenance calendar |
|
The Claude Code auto-approve system is a credential exposure vector. Every approved command is stored in plaintext. If you ever approved a command with a hardcoded credential, that credential is now in |
Metadata
| Field | Value |
|---|---|
CR ID |
CR-2026-02-26-001 |
Author |
Evan Rosado |
Date Created |
2026-02-26 |
Status |
Emergency - Completed (Rotation Pending) |
Category |
Security / Credential Management |