
研究:公开GitHub上Claude Code配置文件泄露3.1万余条密钥
来源标题:31,088 secrets in Claude Code's .claude/settings.local.json on public GitHub
GitGuardian研究员发现,公开GitHub仓库的Claude Code配置文件.claude/settings.local.json中共有31,088条密钥,涉及23,276个仓库,检测时5,343条仍然有效。Docker Hub镜像中另有613条,其中99条有效。泄露源于开发者将本地设置文件误提交至公开仓库。
以下正文由 AI 翻译自 Hacker News 最新(原文版权归原站所有),可能存在偏差,重要内容请以原文为准。
GitHub 公开仓库中 Claude Code 的 .claude/settings.local.json 里存在 31,088 个密钥,检测时 5,343 个有效,涉及 23,276 个仓库。Docker Hub 镜像中另有 613 个,其中 99 个有效。有效性、时间线、Docker Hub、受影响人群。
Guillaume 是 GitGuardian 的网络安全研究员,拥有网络方向博士学位。他喜欢分析数据、构造数据包,是 Scapy 的共同维护者,而且他至今还记得 AT+MS=V34 是什么意思!
我做研究已经很久了,而一个值得做的问题往往会先被别的同行盯上——这既是好迹象,也让人一开始有点郁闷。这个题目最早是在 2026 年初,我研究 n8n 时不断在 Claude Code 的设置文件里发现 n8n API 密钥。11 月 5 日,Apiiro 发布了他们对 .claude/settings.local.json 的分析。下面是我原本计划在《State of Secrets Sprawl 2027》中发布的结果,数据刷新到本周,并补上了只有持续监控才能看到的部分:我们看到每一个被推送过的文件版本、凭据是否可用、是谁推送的,以及文件离开 GitHub 之后去了哪里。
先说让我盯上这条线的案例。你让 Claude Code 列出 n8n 实例上的工作流,它给出:
curl -H "X-N8N-API-KEY: n8n_api_9f3c…e21a" https://n8n.example.internal/api/v1/workflows
Claude Code 在执行 shell 命令之前会先询问。你回答"是,且不要再问",因为你整个下午都要调这个 API。命令执行完,它把一条 allow 规则写进项目目录下的 .claude/settings.local.json。这条规则就是命令字符串本身,API 密钥也一并写了进去。Claude Code 在你本机上会让这个文件不进 git,但仓库本身没有任何机制阻止它——换一台机器、用一个旧的克隆,或者文件本来就被跟踪过,它就会和其他内容一起被提交。
GitGuardian 会在每次推送时扫描每一个公开 commit。Apiiro 的代码搜索是在 11 月 1 日至 3 日看到默认分支上的这些文件,另外还对 43,120 个仓库和 211 个 fork 做了一遍历史扫描。我们则是在每个版本被推送时就看到了,包括后来被删除、改写或 force-push 掉的版本。公开 GitHub,2025 年 1 月至 2026 年 11 月 7 日:
Apiiro 在 settings.local.json 的当前副本中数出 1,379 个密钥,加上历史记录共 734 个。我们数出 31,088 个。这两个数字回答的是不同的问题。他们问的是今天暴露了什么,用了保守过滤且没有做有效性检查。我们问的是曾经被推送过什么,并且统计了自动检查在检测时判定有效的每一个凭据。两个数字都对,而第二个才是应该被轮换的凭据数量。
Apiiro 选择不测试有效性。GitGuardian 对每一个公开检测结果都做自动的只读检查,本文没有重放任何请求。在检查给出结论的样本中,settings.local.json 里 67% 的出现是有效的,settings.json 里是 57%。在我们发现的所有内容里,31,088 个不同的密钥中有 5,343 个(17%)在检测时可用——而这是一个本应永不离开笔记本电脑的文件。没有校验器的检测器永远不会被计为有效,所以这些都是下限。
curl 调用里的 bearer token 构成了数量的大头,真正能用的是数据库凭据。仅 settings.local.json 一个文件就包含 1,955 个不同的有效 Postgres 连接串(5,076 次有效出现)、292 个有效 SSH 密码、116 个有效 MongoDB URI、941 个有效 Google API 密钥、355 个有效 Telegram bot token、142 个有效 Resend 密钥和 186 个有效 DeepSeek 密钥。按类别看,数据库标识符是最大的活跃桶,有 2,280 个不同的有效密钥;其次是云厂商 token,971 个;然后是 AI token,583 个。
我们在大约 3,000 次出现的样本上定位了每个密钥在文件中的位置,看是哪条规则携带了它。每一个我们能定位的密钥都位于 allow 规则或 env 块中,没有一个是位于 deny 中的:
bearer token、JWT、-u user:pass、Supabase service-role 密钥、header 里的 API 密钥
PGPASSWORD=、DATABASE_URL=、SUPABASE_ACCESS_TOKEN= 以及其他 VAR=value 命令前缀
Postgres 密码和 URI,以及 Supabase token
psql、mysql、mongosh、redis-cli、cd … && psql
WebFetch(url:https://user:pass@…)、Read(/path/with/token)
URL 和路径中的凭据,完全不是 shell
数量来自 curl,有效凭据是数据库和 SSH。
同样的分布也解释了扫描器的盲区。Apiiro 测出 gitleaks 和 TruffleHog 合起来会漏掉五分之一的泄露文件。在我们的数据里,通用检测器(密码、高熵字符串、JWT、bearer token、用户名密码对)贡献了 settings.local.json 全部出现次数的 63%:71,525 次中的 44,755 次。PGPASSWORD= 后面的密码没有前缀可供匹配。一个只认识厂商密钥格式的扫描器,对这个文件的大部分内容都是瞎的。
.claude/settings.json——团队有意提交的共享项目文件——泄露还有第二个原因。它泄露版本中有四分之一包含一个 env 块,把 Claude Code 指向第三方 Anthropic 兼容网关:ANTHROPIC_BASE_URL 加上 ANTHROPIC_AUTH_TOKEN。这些主机包括 DeepSeek、OpenRouter、Z.ai、MiniMax、阿里的 DashScope、Kimi、Moonshot,以及一长串转售商。泄露的凭据是网关的:settings.json 中有 205 个有效 DeepSeek 密钥、62 个有效 OpenRouter 密钥、50 个有效 MiniMax 密钥。真正的 Anthropic API 密钥在两个文件中都很罕见:settings.local.json 中有 139 个不同密钥,其中 28 个有效。
Apiiro 对比了他们文档中的 16 个 agent,发现 Claude Code 是唯一一个默认把完整获批命令写入项目文件的。我们的数据也印证了这一点。我们统计了公开 GitHub 上 30 个 agent 的配置文件。它们全都泄露,而且泄露方式相同:env 块里带 API 密钥的 MCP server 定义。按每个文件的检测器类型组合判断,只有 .claude/settings.local.json 以输入到命令中的凭据为主——而这正是持久化审批的样子。
(原文较长,此处译出前 6000 字,完整内容请点「打开原文」。)
正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。