deniz.in

Markets

Weather

Loading weather

· via dev.to (home feed)

Claude Code 'don't ask again' rules left secrets in 1,122 public settings files

Apiiro found 1,122 public copies of Claude Code's local settings file containing secrets, and 215 of those files were missed by both gitleaks and TruffleHog.

Claude Code 'don't ask again' rules left secrets in 1,122 public settings files

The scan and the numbers

Security firm Apiiro went looking on public GitHub for .claude/settings.local.json, the file Claude Code writes when a user approves a command with "Yes, and don't ask again". As The Hacker News reported on November 7, and as a dev.to write-up by Gabriel Anhaia details, the firm examined 104,185 copies of that file across 103,617 public repositories and found 1,122 copies holding at least one secret — 1,379 distinct credentials in total.

The headline problem is detection: gitleaks flagged 564 of the 1,122 affected files and TruffleHog flagged 643, and per the report 215 were missed by both.

How an approval becomes a plaintext secret

When a user picks "Yes, and don't ask again", Claude Code saves the command as a lasting allow rule in .claude/settings.local.json at the root of the repository. Rules sometimes take a pattern form (the documentation's example is npm test *), but exact-command rules record the full command text — password included. An August 2025 bug report observed that commands carrying credentials were saved verbatim, in plain text, inside that file.

According to the report, Apiiro's researchers reproduced this with current models, which the write-up names as Opus 5.5 and Fable 5.1. Of 16 coding agents whose documentation they compared, Claude Code was the only one confirmed to persist the full approved command in a project file by default.

Why the built-in guard doesn't travel

Claude Code does try to keep the file out of git: its settings documentation says the first time it writes the file in a repository, it adds it to the user's global git excludes file. That protects a single machine. A global exclusion is never committed, so it doesn't follow the repository to a teammate's clone, a CI runner or a fresh laptop. A file created by hand gets no exclusion at all, and no ignore rule can untrack a file that was already committed.

The agent itself appears to be doing some of the committing: in 539 of the 1,105 repositories Apiiro could trace, a commit listing Claude as co-author changed the file. The shared team file is exposed too — 298 of 76,011 public copies of .claude/settings.json, which teams commit deliberately, held a secret. The VS Code extension's approval card can route a rule to that shared file; the CLI always writes to the local one.

What was in the files

More than a third of the secrets opened databases directly, including 379 database passwords. The count also includes 43 SSH logins for public servers, 42 GitHub, GitLab and npm tokens, and 23 AWS keys; GBHackers adds 122 Supabase service-role keys. The affected files belong to 63 organizations, which the report describes as mostly software companies.

The blast radius is larger than current file contents: git history held 734 more secrets across 509 repositories, and 211 forks of 74 repositories carry the same credentials. Including shared settings, history and saved agent chat logs, GBHackers puts the total at 2,539 secrets across 1,994 repositories.

The methodology has limits. Apiiro counted a value as a secret when it matched a known key format, or when a password or token sat next to a public server address and an AI-assisted review concurred, and the firm did not check whether the credentials were still valid. One company it notified did confirm its key had been live. Most of the 215 scanner misses were passwords embedded inside commands — after PGPASSWORD=, sshpass -p or mysql -p — which lack the provider prefix that pattern-based scanners rely on.

What users should do

The order matters: Apiiro's advice, relayed by The Hacker News, is to rotate every credential the files contained before cleaning anything up, because a public secret stays compromised regardless of any history rewrite, and forks keep their own copies. After rotating, untrack the file and ignore it inside the repository itself, and run /permissions in Claude Code to inspect every saved rule.

Prevention is largely about keeping literals out of command text: referencing an environment variable (PGPASSWORD="$DB_PASSWORD") saves the variable name rather than the value, and approving command patterns instead of one-off commands keeps arguments out of rules entirely. Apiiro also recommends treating agent directories like .env files — adding them to organisational ignore templates and scanning .claude/, .cursor/, .gemini/ and .specstory/ in pre-commit hooks and CI, history included.

Notably, the dev.to post points out that the original 2025 bug report was closed by a bot as "not planned" on January 3, 2026 after 60 days of inactivity, so waiting on a product change is not much of a plan.

Why it matters

This is a practical security incident for anyone using AI coding tools, not a theoretical concern. A convenience feature meant to cut down on approval prompts became a mechanism for persisting plaintext credentials into project files, and those files reach public GitHub — sometimes committed by the agent itself. Worse, the credentials that leak this way are exactly the ones mainstream scanners are worst at catching: inline passwords with no recognizable prefix. As coding agents take over more of the commit workflow, their permission and config files deserve the same hygiene as .env.

  • #claude-code
  • #security
  • #secrets
  • #github
  • #ai-coding

Related posts