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

BORG_PASSPHRASE="<plaintext>"

Backup repository access

4

ISE ERS API

ISE_API_TOKEN="<base64>"

ISE admin access

10+

ISE DataConnect

ISE_DC_PASS=<plaintext>

ISE database access

3

pfSense API

X-API-Key: <hex>

Firewall admin access

1

Secrets Wildcards

dsec show:*, dsource d000:*

Access to ALL secrets

4

Decrypt Wildcard

~/.secrets/bin/decrypt-file:*

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

  1. User approves command with hardcoded credential

  2. Claude Code saves full command text to settings.local.json

  3. File persists indefinitely without review

  4. Wildcard patterns (dsec:*) grant access to ALL secrets

Prevention Checklist

When Approving Commands

  • Never approve commands with literal credentials

  • Use $VAR references only (e.g., $BORG_PASSPHRASE)

  • Never approve dsec show:* or dsource:* 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 $VAR references, never literal values

Wildcards grant excessive access

Never allow dsec:* or dsource:* - too broad

Shell history contains secrets

Use HISTCONTROL=ignorespace and HISTIGNORE

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 settings.local.json until you remove it.

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