[security] Redact known-secret file patterns in file-modification system-reminder content

Resolved 💬 2 comments Opened May 30, 2026 by maxmk000 Closed Jun 2, 2026

Harness file-modification system-reminder leaks file contents -- upstream fix proposal

Date: 2026-05-28
Status: PROPOSAL

Observed behavior

Claude Code's harness fires a <system-reminder> injection into the conversation transcript whenever it detects that a tracked file has been modified -- either by the assistant (Write/Edit) or external party (user, linter, sub-agent). The reminder contains:

  • File path
  • Boilerplate sentence noting the change is intentional
  • Full contents of the file up to a high truncation threshold (~190 lines observed)

For most files this is great (model gets fresh context on edits). For files containing plaintext secrets, it's a leak surface.

Leak events observed in one session

Event 1: Assistant Edit on .env

Goal: add a comment block above a Cloudflare API token line documenting required scopes. Edit landed at line ~273. Harness then dumped lines 1-168 of .env, exposing 8 high-value secrets (database DSN, app secret key, third-party OAuth client secret, Anthropic API key + admin key, two vendor API keys, an SMTP password).

Event 2: User modification of .env.rotation_2026_05_28

Recovery path: create a gitignored paste-board file for new tokens. User pasted. Within seconds, the harness fired a modification reminder dumping the FULL file -- 8 freshly-minted tokens in the transcript.

Net: 2 leak events, ~16 distinct secret exposures, forced a 13-secret rotation cycle in one session.

Why existing mitigations were insufficient

After Event 1, a memory hook saved: "never Edit .env directly; use docs/*.md". Prevented future .env edits. Did NOT prevent Event 2 because:

  • Paste-board was a NEW file with different name (.env.rotation_2026_05_28)
  • User modification (not assistant) still triggers the dump
  • .env* glob matches secrets-likely file convention universally

The current behavior is a structural leak surface for ANY session touching secrets.

Proposed mitigation (3 options, ranked)

Option 1 (highest leverage): Content redaction for known-secret patterns

When the harness emits a file-modification system-reminder, check file path against a pattern list:

  • .env, .env.*, .env*.local, .env*.production
  • secrets/, credentials/
  • *_secret.py, *_secrets.py
  • *.pem, *.key, *.crt, *.pfx, *.p12, *.jks
  • gcloud-credentials*.json, *service-account*.json, *-credentials.json

If matched: include file PATH + DIFF SUMMARY (line count delta, lines-added/lines-removed) but NOT contents. The summary is enough for the model to know "user updated 3 lines in .env" without leaking values.

Option 2: User-configurable redaction list

In .claude/settings.json or per-project .claude/redaction.json, the user declares files/patterns that should NEVER appear in file-modification reminders.

Pros: zero hardcoded patterns; user controls.
Cons: requires user to anticipate; misconfiguration = leak.

Option 3: Opt-IN file-modification reminders

Flip default to opt-IN. Solves secrets case but loses model fresh-context benefit. Too aggressive; Option 1 is better.

Recommendation

Option 1 with sane defaults. Conservative patterns matching >90% probability of containing secrets. Files in those patterns get diff-only summaries; everything else keeps existing behavior.

Operational practice today (until upstream lands)

  • Never create paste-board files for secrets. Use STDIN-only handoff (e.g. a small script using getpass.getpass(), values never touch disk).
  • Never Edit/Read/Grep .env from assistant context.
  • All env-var setup docs go to docs/*.md.

Action

Anthropic should evaluate. Option 1 with conservative defaults is the lowest-risk close on the structural leak surface.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗