Claude Code 的「不再询问」按钮,把密码写进了公开仓库
一个图省事的按钮,变成了密钥仓库。应用安全公司 Apiiro 在公开 GitHub 上数出了 2,539 个真实密钥,分布在 1,994 个仓库里,绝大多数都是同一个来路:开发者在 Claude Code 里点了「Yes, and don't ask again」。研究 11 月 5 日发布,周六冲上了 Hacker News。
机制很简单。让 Claude Code 查一下 staging 为什么登不上,它给出的命令里就带着数据库密码,不带根本跑不起来。你选永久批准,Claude Code 就把这条命令原样存成 allow 规则,写进项目目录下的 .claude/settings.local.json,密码一起。它会把这个文件加进开发者的全局 gitignore,却从不写进仓库自己的 .gitignore。于是换台机器 clone、后来才变成仓库的文件夹、早就提交过的文件,统统不受保护。在追溯的 1,105 个仓库里,有 539 个是 Claude 署名合著的 commit 亲手改了这个文件。
数字都来自 Apiiro:这个文件在公开 GitHub 上有 104,185 份,1,122 份带真密钥,其中 379 个数据库密码、122 个 Supabase service-role key、43 个 SSH 登录,涉及 63 家机构,包括一家数据库厂商自己的管理级云密钥。最该让安全团队坐不住的是这条:gitleaks 只抓到 564 个文件,TruffleHog 抓到 643 个,有 215 个两个都没抓到。扫描器认的是密钥格式,PGPASSWORD= 或 sshpass -p 后面敲的密码,在它眼里就是命令行里的一个普通单词。同样的问题还出现在 agent 对话记录和 MEMORY.md 里。Apiiro 说它对比了 16 个编程 agent,只有 Claude Code 默认把完整命令写进项目文件。用户从 2025 年 8 月起就在 GitHub issue 里报过,Apiiro 说一条都没等到 Anthropic 回复,我们这边也没找到官方回应。
这是安全厂商的研究,带着推销,打个折看。但修起来很便宜:在组织里搜 .claude/settings.local.json,git rm --cached 掉,写进仓库自己的 .gitignore,把它存过的所有凭证全部轮换。以后批准用模式,比如 Bash(npm run:*),别批准字面命令;密钥用 $DB_URL 这种变量引用,规则里记下的就是变量名而不是值。
更大的问题是:现在每个 agent 都在给自己跑过的命令记日记,这本日记成了凭证的新落脚点。.claude/、.cursor/ 和各种记忆文件,请当成 .env 对待,因为它们实际上已经是了。
原文:https://apiiro.com/blog/coding-agents-leaking-secrets-github-dont-ask-again
← 返回所有文章
机制很简单。让 Claude Code 查一下 staging 为什么登不上,它给出的命令里就带着数据库密码,不带根本跑不起来。你选永久批准,Claude Code 就把这条命令原样存成 allow 规则,写进项目目录下的 .claude/settings.local.json,密码一起。它会把这个文件加进开发者的全局 gitignore,却从不写进仓库自己的 .gitignore。于是换台机器 clone、后来才变成仓库的文件夹、早就提交过的文件,统统不受保护。在追溯的 1,105 个仓库里,有 539 个是 Claude 署名合著的 commit 亲手改了这个文件。
数字都来自 Apiiro:这个文件在公开 GitHub 上有 104,185 份,1,122 份带真密钥,其中 379 个数据库密码、122 个 Supabase service-role key、43 个 SSH 登录,涉及 63 家机构,包括一家数据库厂商自己的管理级云密钥。最该让安全团队坐不住的是这条:gitleaks 只抓到 564 个文件,TruffleHog 抓到 643 个,有 215 个两个都没抓到。扫描器认的是密钥格式,PGPASSWORD= 或 sshpass -p 后面敲的密码,在它眼里就是命令行里的一个普通单词。同样的问题还出现在 agent 对话记录和 MEMORY.md 里。Apiiro 说它对比了 16 个编程 agent,只有 Claude Code 默认把完整命令写进项目文件。用户从 2025 年 8 月起就在 GitHub issue 里报过,Apiiro 说一条都没等到 Anthropic 回复,我们这边也没找到官方回应。
这是安全厂商的研究,带着推销,打个折看。但修起来很便宜:在组织里搜 .claude/settings.local.json,git rm --cached 掉,写进仓库自己的 .gitignore,把它存过的所有凭证全部轮换。以后批准用模式,比如 Bash(npm run:*),别批准字面命令;密钥用 $DB_URL 这种变量引用,规则里记下的就是变量名而不是值。
更大的问题是:现在每个 agent 都在给自己跑过的命令记日记,这本日记成了凭证的新落脚点。.claude/、.cursor/ 和各种记忆文件,请当成 .env 对待,因为它们实际上已经是了。
原文:https://apiiro.com/blog/coding-agents-leaking-secrets-github-dont-ask-again
评论