Claude Code leaks passwords in 1,122 public GitHub files by saving approved commands

- Reading
- 7 min
- Tables
- 1
Research from Apiiro found 2,539 real secrets, such as database passwords and cloud keys, scattered across 1,994 public GitHub repositories, because of how Claude Code saves commands approved by the user.
What the research found
Security firm Apiiro published a report on November 5, 2026, showing how a default behavior of Claude Code, Anthropic's coding agent, results in real credentials exposed in public GitHub repositories. Scanning GitHub between November 1 and 3, 2026, the company found 2,539 real secrets, such as database passwords, cloud keys, API tokens, and SSH logins with root privileges, scattered across 1,994 public repositories.
63 organizations were affected, most of them software companies of all sizes. One of them confirmed to Apiiro that the leaked key was active at the time of discovery. Among the most serious findings are a database vendor's own admin-level API key, the production password of an Azure Postgres instance, a production token from Square, and the admin password of a database for an electronic health record system.
How the leak happens in practice
The problem stems from a convenience feature. When Claude Code needs to run a shell command, for example to query a database and understand why login fails in staging, it asks for confirmation before executing. If the developer chooses the option "Yes, and don't ask again," the agent saves the exact command, secret included, as a permanent rule in .claude/settings.local.json, inside the project folder.
The file is supposed to stay only on the developer's machine, and Claude Code itself tries to keep it out of version control: when it creates the file inside a git repository, it adds the entry to the user's global gitignore. That covers the common case, but it doesn't cover a folder that later becomes a repository, a clone on another machine, or a file someone already committed before. The rule never goes into the repository's own .gitignore, so nothing travels with the project to protect it.
In many cases, the agent itself makes the commit: Apiiro traced 1,105 repositories with a real secret and found a commit co-authored by Claude Code changing the file in 539 of them, citing models ranging from Sonnet 4.5 to Opus 5.5.
In short: the behavior belongs to the Claude Code product, not to the model behind it. Apiiro reproduced the same pattern with Opus 5.5 and Fable 5.1, which rules out the hypothesis of an isolated failure in a specific model.
The scale of the problem
GitHub has 104,185 public copies of the .claude/settings.local.json file, spread across 103,617 repositories. Of these, 1,122 (1.1%) hold at least one real secret, adding up to 1,379 distinct secrets. The breakdown of what leaked:
- 636 provider keys in recognizable format (AWS, GitHub, npm, Supabase, Stripe, Slack, OpenAI, among others)
- 743 passwords or tokens associated with public hosts
- 379 database passwords and 122 Supabase service keys
- 103 Supabase account tokens, which grant access to all projects in the account
- 43 SSH logins, some with root passwords
- 23 AWS keys and 6 private keys
The bigger the file, the bigger the risk: one in ten files larger than 8 KB has a real secret, versus less than one in 500 below 500 bytes. This happens because the more time a developer spends clicking "don't ask again," the more commands (and secrets) accumulate in the permission list.
The problem is also old and persistent: in the median affected repository, the file was first committed 217 days before the scan, and in 118 repositories, more than a year ago. Deleting the file doesn't fix it: 734 real secrets appear only in old versions of the git history, in 509 repositories where the file has already been removed from the current state. Forks also copy the problem: 211 forks of 74 repositories carry the same secrets.
Affected organizations
Apiiro documented specific cases, all confirmed in commits pinned by hash:
| Organization | What leaked |
|---|---|
| Database vendor | Own cloud API key, with management permissions and no expiration date |
| B2B startup | Production password for an Azure Postgres instance |
| Software agency | Production token from Square |
| Open source project (+1,000 stars) | API key in OpenAI format |
| Open source project | npm token |
| IT company (electronic health record app) | Admin password for cloud Postgres |
| Payments startup | Password for the postgres role |
Why secret scanners don't catch this
Tools like gitleaks and TruffleHog are tuned to recognize key formats: provider prefix, long random string. Running both over the 104,185 files, Apiiro saw gitleaks flag 564 of the 1,122 files with a real secret, TruffleHog flag 643, and 215 were flagged by neither of the two.
The gap is the password inside the command. A password typed after PGPASSWORD=, sshpass -p, or mysql -p, or an auth header in a curl call, is just a common word in a common command line, and both scanners miss it most of the time. This matters beyond this specific file: the same pattern shows up anywhere an agent logs what it executed, such as chat transcripts and handoff notes.
It's not just one file
Apiiro found the same kind of leak in other files that teams commit on purpose or out of habit: the shared settings.json, the team version of the same mechanism, had 298 files with secrets among 76,011 checked. Agent chat transcripts (.specstory, aider, Cursor exports) added up to 120 files with secrets across 87 repositories, and agent memory files (MEMORY.md and similar) appeared in 9 repositories, as did GitHub Copilot auto-approval settings in VS Code.
A third of the handoff notes with a secret were written by the agent itself. The leak also shows up outside GitHub: 126 of the 31,053 Hugging Face Spaces checked have the .claude/settings.local.json file public, one of them with a database service key and a user password. On GitLab.com, 2 of the 69 public copies checked had a real secret, including an access token for GitLab itself.
The risk doesn't go away if the file isn't public
Even when the file never leaves the developer's machine, it's still a plain-text JSON in the project folder, and that's already a risk. Apiiro points out that malware already harvests credentials from developer machines at scale: in September 2025, the Shai-Hulud worm, which spread through npm, downloaded TruffleHog and ran it over the victim's files. That same scanner flags 643 of the 1,122 files found by Apiiro.
Three weeks earlier, malicious Nx packages instructed the victim's own Claude Code and Gemini CLI to scour the disk for secrets. The file can also leak without ever touching git: inside a published npm package, in a Docker image built with a copy command, in a zip file, or in a synced folder. And a secret approved once stays there until someone manually deletes the rule, long after the original command has been executed.
The problem isn't new, but it was never fixed
Developers have been reporting this exact mechanism in issues opened on the Claude Code repository since August 2025 (#5544, #11982, #13106, #91270), none of them answered by Anthropic and three closed automatically due to inactivity or duplication. The company ironPeak had already found the same file with secrets in February 2026, measuring 2.4% of repositories with AI configuration folders carrying secrets in their history, in a sample of 100. Lakera, for its part, found credentials in 33 files of this type distributed across 30 npm packages in April 2026.
Apiiro's report is the first to measure the full scale on GitHub and cross-reference it with the other agent files that carry the same risk. The company reported each organization's case to its respective owner on November 2 and 3, 2026.
What to do if you use Claude Code
For developers, the response playbook is straightforward:
- If the file is tracked in a repository, run
git rm --cached .claude/settings.local.jsonand add the entry to the repository's own.gitignore, not just the global gitignore. - Rotate every credential the file has ever stored. Removing the file from the current state doesn't clean up git history, forks, or clones.
- Even if the file was never committed, open it and delete every rule that contains a literal secret.
- Stop typing secrets inside commands: reference them as
$VARfrom your secrets manager, so the saved rule is$DB_URL, not the real value. - Prefer approving patterns, such as
Bash(npm run:*), instead of whole literal commands.
For security teams, the message is to treat agent folders like .claude/, .cursor/, .gemini/, and .specstory/, as well as memory files, as secret files, on the same level as .env, both on laptops and in repositories. That means including these folders in pre-commit and CI scanning, with a scanner capable of catching passwords inside commands (patterns like PGPASSWORD=, sshpass -p, mysql -p, bearer token headers), not just known key formats, as well as adding .claude/settings.local.json to the organization's .gitignore templates.
Translated from the Brazilian Portuguese original · Read the original
METR Report Shows Anthropic Using AI to Accelerate AI Development
An independent report by the safety organization METR shows that Anthropic's models are evolving about twice as fast as a year ago, and that AI itself is now the biggest driver of that acceleration. The company, however, censored most of the evidence before making the report public.





