Hacker News Best

Claude Code's "Don't Ask Again" exposes passwords in 1,122 public GitHub files

8.5内容质量
Claude Code's "Don't Ask Again" exposes passwords in 1,122 public GitHub files

TL;DR · AI 摘要

Claude Code的‘Don’t Ask Again’功能导致1,122个GitHub文件泄露敏感信息,包括数据库密码和API密钥。

核心要点

  • 1,122个GitHub文件泄露了数据库密码、云密钥等敏感信息
  • 选择‘Don’t Ask Again’会将含密钥的命令保存到.claude/settings.local.json
  • TruffleHog和gitleaks工具仅能检测出643个泄露文件

结构提纲

按章节快速跳转。

  1. Apiiro研究发现2,539个敏感信息泄露在GitHub仓库中。

  2. Claude Code将含密钥的命令保存到项目文件夹的配置文件中。

  3. 通过搜索.claude/settings.local.json文件可确认是否受影响。

  4. 63家软件公司受影响,包括医疗记录数据库管理员密码。

  5. 即使文件已删除,Git历史记录仍可能保留敏感信息。

思维导图

用一张图看清主题之间的关系。

查看大纲文本(无障碍 / 无 JS 友好)
  • Claude Code泄露秘密
    • 泄露机制
      • 保存命令到配置文件
      • 未标记私有文件
    • 检测方法
      • 搜索特定文件
      • 检查Git历史记录
    • 影响范围
      • 63家公司受影响
      • 医疗数据库泄露

金句 / Highlights

值得收藏与分享的关键句。

#GitHub#安全#AI工具#密码泄露
打开原文

Apiiro 研究在 1,994 个公开的 GitHub 仓库中发现了 2,539 个真实机密:数据库密码、云密钥、API 令牌、SSH 根登录凭证。其中包括:某数据库厂商自身的管理员级云密钥、生产环境 Azure Postgres 密码、Square 生产环境令牌,以及某医疗记录数据库的管理员密码。63 家组织受到影响,其中一家确认其密钥已被公开。

当要求 Claude Code 检查数据库或调用 API 时,它提出的命令会直接从你的配置文件中携带机密信息。执行前会先询问用户。若选择“是,且不再询问”,该命令(包含机密)会被保存到项目文件夹内的 .claude/settings.local.json 文件中。仓库中没有任何标记表明该文件为私有,因此它会随代码一起被提交。

在 GitHub 上,该文件的 104,185 个公开副本中,有 1,122 个包含真实机密。我们在 git 历史记录中发现了 1,160 个更多机密,这些机密存在于团队故意提交的共享 settings.json 文件中,以及保存在仓库中的代理聊天记录中。

GitHub 仅仅是我们的统计范围。相同文件以明文形式存在于每个点击过“不再询问”的笔记本电脑上。恶意软件已能批量收集开发者机器上的凭证。Shai-Hulud npm 蠕虫曾在受害者文件上运行 TruffleHog;该扫描器也标记了我们发现的 1,122 个文件中的 643 个。其中五分之一的文件既未被 gitleaks 也未被 TruffleHog 标记,通常是因为机密是命令中输入的密码,而非可识别格式的密钥。

检查你是否受影响

是否公开? 在你的 GitHub 组织中搜索 .claude/settings.local.json 和 .claude/settings.json。每个搜索结果都是当前任何人都可读取的文件。

是否曾被提交? 即使文件今天已被删除,也要检查每个仓库的 git 历史记录。如果历史记录中存在该文件,所有分支和克隆版本也都会存在。

文件内容是什么? 在你的设备上找到该文件的所有副本并查看其允许列表。每个条目都是你批准的命令及其输入内容:查找密码、令牌、密钥和连接字符串。

发现机密? 首先轮换密钥,其次清理文件。

机密如何进入设置文件

开发机器存储着机密:配置文件中的数据库连接字符串、本地安装中的云密钥、.env 中的 API 令牌。当要求 Claude Code 检查预发布环境登录失败原因或执行迁移时,它提出的命令会携带这些机密,因为没有它们命令无法执行。Claude Code 在执行 shell 命令前会多次询问用户。若选择“是,且不再询问”,它会执行命令并在项目文件夹的 .claude/settings.local.json 中添加权限规则,避免再次询问。规则本身即为命令字符串:

Image 1
Image 1

这是 Claude Code 的自身行为,而非模型特性:即使是 Anthropic 最新模型也会出现此问题,我们已在 Opus 5.5 和 Fable 5.1 上复现了该现象。

该文件本应保留在开发者的机器上,Claude Code 也尽量将其保留在本地。当它在 Git 仓库内创建文件时,会将其添加到开发者的_全局_ Git 忽略列表中。这覆盖了常见场景,但无法应对后续变成仓库的文件夹、其他机器上的克隆版本,或已被提交的文件。该规则永远不会写入仓库自身的 .gitignore,因此没有任何内容会随项目一起传输以保护文件。

Claude 经常直接提交该文件。在我们追踪的 1,105 个包含真实密钥的仓库中,有 539 个仓库的提交记录显示 Claude 作为合著者修改了该文件。这些提交记录中列出了所有近期模型,从 Sonnet 4.5 到 Opus 5.5。

被暴露的实体

63 家组织在公开的白名单中持有真实密钥。最严重的案例均位于 .claude/settings.local.json,且每个案例都对应特定提交版本:

| 组织类型 | 暴露内容 | | --- | --- | | 数据库供应商 | 其云服务管理权限 API 密钥(无过期声明)及集群主机地址 | | B2B 初创公司 | 生产环境 Azure Postgres 数据库密码 | | 软件代理机构 | Square 生产环境访问令牌 | | 开源项目(超 1,000 星标) | 符合 OpenAI 格式的 API 密钥 | | 开源项目 | npm 访问令牌 | | 医疗记录应用 IT 服务商 | 应用云 Postgres 数据库管理员密码 | | 支付领域初创公司 | Postgres 角色数据库密码 |

多数为公司实体:初创企业、软件代理机构、IT 服务商。少数为成熟供应商,其演示和工作坊仓库中意外暴露了密钥。没有人本意公开密钥,密钥存在于命令中,命令获得批准,文件随其他内容一同提交。

白名单中还包含服务器登录凭证:43 组公共服务器的 SSH 凭据,其中部分命令包含 root 密码。例如,某大学仓库永久批准了连接公共服务器的 root SSH 命令。

数量统计

GitHub 公共仓库中存有 104,185 份 .claude/settings.local.json 文件,分布在 103,617 个仓库中。其中 1,122 个文件(1.1%)包含真实密钥:符合已知供应商格式的密钥,或与公共主机相邻的密码/令牌。总计包含 1,379 个独立密钥:636 个供应商密钥和 743 个公共主机密码/令牌。

超过三分之一的密钥可直接访问数据库:379 个数据库密码和 122 个 Supabase 服务角色密钥。另有 103 个 Supabase 账户令牌(可控制账户内所有项目)。其余密钥主要为第三方服务 API 令牌、AI 模型密钥,以及 43 个 SSH 登录凭证、42 个 GitHub/GitLab/npm 令牌、23 个 AWS 密钥和 6 个私钥。

Image 2
Image 2

大型白名单显著提升暴露率:文件大小超过 8KB 时,每 10 个文件中就有 1 个包含真实密钥;而文件大小低于 500 字节时,每 500 个文件中不足 1 个。开发者连续点击“不再提示”的时长越长,文件中存储的敏感信息越多。

Image 3
Image 3

这些文件依然存在:截至 2026 年 11 月 2 日,所有文件均位于其仓库的默认分支上,其中大多数已长期驻留。在包含真实密钥的仓库中,文件平均在 217 天前首次提交。118 个仓库的文件提交时间甚至超过一年。

分支会复制这些文件:74 个仓库的 211 个分支携带相同密钥。

删除文件并不能解决问题。文件早期版本中包含734个真实密钥,分布在509个仓库中,这些密钥在当前版本中均未出现,通常是因为文件被删除了。

统计文件历史记录、共享设置文件和代理转录内容(下一章节),总计发现1,994个仓库中存在2,539个真实密钥。

秘密扫描器的遗漏

通用秘密扫描器会遗漏大量此类密钥。我们对全部104,185个文件运行了gitleaks和TruffleHog。在包含真实密钥的1,122个文件中,gitleaks标记了564个,TruffleHog标记了643个,有215个文件未被任何工具标记。

遗漏的关键在于命令中的密码。扫描器寻找特定格式:供应商前缀加长随机字符串。当密码出现在PGPASSWORD=、sshpass -p、mysql -p或curl调用的bearer header中时,这些密码在普通命令行中只是普通单词,两种工具通常都会忽略。

Image 4
Image 4

这个问题的影响不限于当前文件。当代理记录执行内容时,密码嵌入命令的模式会出现在各种场景中:转录文件、内存文件、交接笔记等,针对密钥格式的扫描器在所有场景中都会遗漏这些密码。

不止一个文件

白名单是最明显的案例,但代理会将密钥写入开发者提交的其他文件中。

| 文件 | 检查数量 | 包含真实密钥 | | --- | --- | --- | | 共享的 .claude/settings.json | 76,011个 | 298个文件 | | 代理聊天转录(.specstory、aider、Cursor导出) | 2,523个 | 87个仓库中的120个文件 | | 代理内存文件(MEMORY.md及类似文件) | 1,200个 | 9个仓库 | | 交接与部署说明 | 2,095个 | 33个文件 | | VS Code Copilot自动批准设置 | 173个 | 9个仓库 |

团队有意提交共享设置文件,其中大部分密钥以精确命令行形式存在于白名单规则中。三分之一的包含密钥的交接说明是由代理自身生成的。

文件泄露不仅限于GitHub。在31,053个Hugging Face Spaces中,有126个包含.claude/settings.local.json,其中1个包含数据库服务密钥和用户密码。在GitLab.com上,我们检查的69个公开副本中有2个包含真实密钥,包括一个GitLab访问令牌。

所有场景中泄露的模式都相同:将密钥输入代理记录的命令中。

开发者本地环境

这些文件大多从未上传到GitHub。它们保留在开发者本地机器上,但这并不意味着更安全。白名单是项目文件夹中的普通JSON文件。

恶意软件已能批量从开发者机器收集凭证。2025年9月,Shai-Hulud npm蠕虫下载了TruffleHog并运行在受害者文件上。该扫描器标记了1,122个真实密钥文件中的643个。三周前,恶意Nx包已指示开发者的Claude Code和Gemini CLI在磁盘上搜索密钥。

文件也可能通过非git方式泄露:发布到npm包中、使用copy命令构建的Docker镜像、zip压缩包或同步文件夹。一旦批准的密钥写入文件,除非有人删除规则,否则会一直保留在文件中,即使相关命令早已执行完毕。

已有研究

本文补充了大规模GitHub秘密泄露的完整数据统计、组织案例、扫描器漏洞以及其他携带相同秘密的代理文件信息。Claude Code用户自2025年8月起已在GitHub Issues中报告该机制(#5544, #11982, #13106, #91270)。Anthropic公司未对任何报告作出回应,其中三个Issue被自动标记为不活跃或重复而关闭。ironPeak于2026年2月在其自有仓库中发现相同文件,抽样调查100个仓库后发现2.4%的历史AI配置文件夹包含秘密。Lakera于2026年4月在30个npm包的33个文件中发现凭证。

应对措施

开发人员:

  1. 若文件已被仓库跟踪,使用 git rm --cached .claude/settings.local.json 停止跟踪,并将其添加到仓库的 .gitignore 文件中。
  2. 旋转文件曾持有的所有凭证。删除文件不会清除Git历史记录、分支或克隆。
  3. 即使文件从未被提交,也应打开文件并删除所有包含秘密的规则。
  4. 停止在命令中输入秘密。通过所使用的秘密管理器以 $VAR 格式引用,使规则记录 $DB_URL 而非具体秘密。
  5. 批准模式(如 Bash(npm run:*)),而非直接使用具体命令。

安全团队:

  1. 将代理文件夹(.claude/、.cursor/、.gemini/、.specstory/)、代理内存文件视为秘密载体,与 .env 文件一样,在本地设备和仓库中均需严格保护。
  2. 将其添加到预提交检查和CI秘密扫描中,包括历史记录。确保扫描器能捕获命令中的密码(如 PGPASSWORD=、sshpass -p、mysql -p、bearer headers),而不仅限于提供商密钥格式。
  3. 将 .claude/settings.local.json 添加到组织的 .gitignore 模板中。
  4. 优先处理与公共主机配对的凭证:这些凭证直接提供访问权限。

披露信息

我们于2026年11月2日和3日将每个组织案例报告给相关机构。其中一家公司确认其密钥曾被公开使用。

方法与限制

数据收集。 所有数据均来自2026年11月1日至3日GitHub默认分支上的只读代码和提交搜索。代码搜索每个查询最多返回1,000个结果,因此我们按文件大小拆分搜索,直到每个片段均低于限制。这列出了103,617个仓库中的104,185个 .claude/settings.local.json 文件,以及76,011个共享的 settings.json 文件,我们下载了所有文件。文件历史覆盖43,120个仓库,包括所有提及删除、停止跟踪、抹除或轮换文件的提交记录的仓库,因此历史统计为下限。分支:所有包含真实密钥的仓库的分支。转录本、内存文件、交接笔记和Copilot设置通过搜索密钥前缀和连接字符串发现;表格显示了我们检查的数量。我们比较了16个编码代理如何存储批准信息,其文档显示Claude Code是唯一默认将完整批准命令写入项目文件的代理。

分类。 我们使用秘密扫描器采用的两类检测器。提供者模式匹配已知的密钥格式:OpenAI、Anthropic、AWS、GitHub、npm、Supabase、Stripe、Slack 等。通用秘密是无特定格式的密码和令牌;只有在公共主机位于同一行时(例如连接字符串或 PGPASSWORD= 在 psql -h 前的场景)才被计数。规则随后会移除已知的误报:占位符、常见默认密码、本地和私有主机、设计上公开的密钥(Supabase 匿名密钥、Firebase Web 配置)、本地 Supabase 示例密钥、过期令牌,以及内置校验和验证失败的 GitHub 和 npm 令牌。所有剩余的 2,774 个唯一值均在遮蔽上下文中由独立的 LLM 审查员根据书面评分标准进行复核。只有当规则与审查结果一致时,该值才会被认定为真实秘密:总计 2,539 个。内存文件、交接笔记和 Copilot 设置仅通过规则进行分类。gitleaks 和 TruffleHog 在未验证的情况下运行。

限制。 未使用或测试任何凭证,也未联系任何主机。"真实秘密"指符合提供者格式或指向公共主机的凭证,而非已知有效的凭证。所有组织案例均通过提交固定链接进行验证。