11 月 5 日,安全公司 Apiiro 说,公开 GitHub 上有超过 10 万份 Claude Code 的本地设置文件,其中约 1,100 份含真实密钥。 四天后,GitGuardian 给出另一个数字:31,088 个,分布在 23,276 个仓库,5,343 个在检测时仍然有效。IT之家GitGuardian
两个数字不矛盾。Apiiro 数的是 11 月 1 日到 3 日默认分支上现存的文件:约 1,100 份带真密钥;GitGuardian 数的是 2025 年 1 月以来所有被推送过的版本里的不同密钥:31,088 个。一个回答“今天还摊在外面多少份文件”,一个回答“历史上到底漏过多少个密钥”。清理时,后一个才是你要处理的量。
机制不复杂。你让 Claude Code 连数据库、调 API,它把带密码的命令递给你确认;你点了 “Yes, and don’t ask again”,它就把整条命令原样写成 allow 规则,存进项目里的 `.claude/settings.local.json`。存的不是“允许执行 psql”,而是 `PGPASSWORD=… psql …` 这一整行。Claude Code 第一次写这个文件时,会把它加进你本机的全局 git 排除。 但仓库自己的 `.gitignore` 里什么都没有。换一台机器、用一个旧克隆,或者这个文件已经被跟踪过,它就会像普通文件一样被提交。Claude Code 文档
Claude Code 负责人 Boris Cherny 在 Hacker News 上回应说,这个文件本应留在本地,团队历史上没有做密钥清洗,正在研究预防办法。 他建议改用自动模式,并开启 GitHub 等平台的密钥扫描。GitGuardian 的核对不太支持“手工”这个说法:在抽查的约 3,000 次出现里,每个密钥都躺在权限提示写出的那种 allow 规则里。 Apiiro 追踪的 1,105 个仓库里,539 个仓库中改到这个文件的提交有 Claude 共同署名。 GitGuardian 还找到 263 个仓库直接把 Claude 记为提交作者。Hacker NewsGitGuardianHacker News
真正还能用的,不是 curl。curl 占了泄露命令的一半,但有效率低;数据库和 SSH 才是硬通货。GitGuardian 在 31,088 个密钥里确认了 1,955 条有效的 Postgres 连接串、292 个 SSH 密码、116 条 MongoDB URI,另有 941 个 Google API key。GitGuardian
更麻烦的是,63% 的密钥没有厂商格式——`PGPASSWORD=` 后面的一串密码、`user:pass@` 里的口令,只认 `sk-`、`ghp_` 这类前缀的扫描器看不见。 Apiiro 的测量是,gitleaks 加 TruffleHog 合起来仍会漏掉五分之一的泄露文件。GitGuardianIT之家
所以别只盯着那一个文件。现在要查的是四处。
一、`.claude/settings.local.json`,连同它的历史
这个文件的 `permissions.allow` 里存的就是原命令。 打开文件看它,或者直接跑 `/permissions`。再确认它有没有被 git 跟踪:`git ls-files – .claude/settings.local.json`;查历史:`git log --all --oneline – .claude/settings.local.json`。有记录就把每个版本翻出来看。删掉工作区里的文件不会删掉历史里的 blob;如果仓库是公开的,还要看 fork。GitHub
二、团队共享的 `.claude/settings.json`
这份是主动提交的,问题在 `env` 块。GitGuardian 发现,四分之一泄露版本里写着 `ANTHROPIC_BASE_URL` 加 `ANTHROPIC_AUTH_TOKEN`——指向 DeepSeek、OpenRouter、MiniMax 之类的第三方网关,他们确认了 205 个有效的 DeepSeek key、62 个 OpenRouter key、50 个 MiniMax key。 国内开发者尤其容易中:把中转站地址和 token 写进项目配置,提交给同事共用,等于把账号交出去。GitGuardian
三、`CLAUDE.md`
这是所有文件里有效率最高的:6,155 个密钥,2,537 个有效。 很多人把数据库连接串、内部地址直接写进给 agent 的说明里。查 `postgres://`、`redis://`、`Bearer`、`token=`。GitGuardian
四、Docker 镜像
`COPY . .` 复制的是工作区,不是 git 索引。`.gitignore` 管不住它,得靠 `.dockerignore` 里写上 `.claude/`。公开 Docker Hub 镜像里有 613 个不同的密钥,99 个有效;一个有效的 Cloudflare token 出现在 559 个 tag 里。 从仓库里删掉文件,已经推上去的镜像还在。顺带查一眼 `.claude/.credentials.json`:371 个仓库把它提交了,1,366 个 token,因为有人把整个 home 目录推了上去。GitGuardian
顺序比清单重要:先轮换,再清理。到对应平台撤销、重置,把钥匙作废;然后才去删规则、补 `.gitignore` 和 `.dockerignore`、用 `git filter-repo` 或 BFG 清历史、强推、重建镜像。反过来做,你只是把复印件从桌上拿走,柜子里、别人的抽屉里还有。
以后再点“别再问我”,让命令里只出现变量名:`$N8N_API_KEY`。规则存的是名字,不是值。 范围也收窄,写 `Bash(curl -H “X-API-KEY: $KEY” https://your-host:)`,别写 `Bash(curl:)`——后者等于批准任何一条 curl,包括别人通过提示注入写的那条。GitGuardian
这件事最刺眼的地方,不是“用户手滑”。一个把“别再问我”当效率卖点的工具,默认把整条命令连同命令里的密码记进项目文件,再把“别提交”交给每台机器各自的全局排除去管。该修的是这个默认值:记住批准的范围,而不是记住批准时看到的那串字符。Anthropic 说还在原型阶段;在它落地之前,这道检查只能自己补。