Apiiro 发布研究称,Claude Code 在用户选择「Yes, and don't ask again」时,会把完整命令(包括命令里的密钥)写入项目内的 .claude/settings.local.json。该文件若随代码被提交到公开仓库,密钥就会暴露。Apiiro 称,在 GitHub 公开的 104,185 份此类文件中,有 1,122 份含真实密钥;这是 Apiiro 自己的统计,并非 Anthropic 的数据。
据 Apiiro 介绍,开发者让 Claude Code 排查登录失败或执行迁移时,它提出的命令往往带着配置里的密钥。用户选择「Yes, and don't ask again」后,这条命令连同密钥会被原样写入 .claude/settings.local.json。
Claude Code 在 git 仓库内创建该文件时,会把它加入开发者的全局 git 忽略列表,但不会写入仓库自己的 .gitignore。Apiiro 指出,以下几种情况不受这一保护:
在 Apiiro 追踪的 1,105 个含真实密钥的仓库中,539 个有 Claude 共同署名的提交修改过该文件。Apiiro 称,用 Opus 5.5 和 Fable 5.1 复现了该行为。
根据 Apiiro 的统计,GitHub 上公开的 .claude/settings.local.json 共 104,185 份,分布在 103,617 个仓库。其中 1,122 份(1.1%)含真实密钥,共 1,379 个不同密钥,包括 636 个服务商格式密钥,以及 743 个公开主机的密码或令牌。
再算上文件历史版本、团队有意提交的共享 settings.json 和 agent 聊天记录,Apiiro 统计的密钥合计 2,539 个,分布在 1,994 个仓库、63 个组织。其中一家公司向 Apiiro 确认,其密钥当时仍然有效。
这些文件在 2026 年 11 月 2 日都还在各自仓库的默认分支上。含密钥的仓库中位数,该文件首次提交距当时 217 天,118 个仓库超过一年;74 个仓库的 211 个 fork 带着同样的密钥。另据 Apiiro,文件历史版本中还有 734 个真实密钥(509 个仓库)不在任何现存副本里,删除文件并不能解决问题。
Apiiro 用 gitleaks 和 TruffleHog 扫描了这批文件。在 1,122 份含真实密钥的文件中,gitleaks 标出 564 份,TruffleHog 标出 643 份,有 215 份两者都未标出。
Apiiro 的解释是,漏报多发生在命令内嵌的密码上,例如 PGPASSWORD=、sshpass -p、mysql -p 之后的口令。扫描器主要识别密钥格式,这类密码在命令行里与普通字符串没有区别。
数据来自 2026 年 11 月 1 日至 3 日对 GitHub 默认分支的只读代码与提交搜索。Apiiro 称没有使用或测试任何凭据,也没有联系任何主机。「真实密钥」指匹配服务商格式或配有公开主机的凭据,不代表已验证有效。Apiiro 于 11 月 2 日和 3 日向相关组织通报。
Apiiro 称,自 2025 年 8 月起就有用户在 GitHub issue(#5544、#11982、#13106、#91270)中反映该机制,均未得到 Anthropic 回复,其中三个因不活跃或重复被自动关闭。
Apiiro 给开发者的建议包括:
git rm --cached 取消跟踪该文件,并加入仓库自己的 .gitignore$VAR 引用密钥,而不是把密钥写进命令Bash(npm run:*) 这类模式,而不是字面命令