AREXOpen in interactive Feed

AREX Feed Article

Apiiro 报告:Claude Code「Yes, and don't ask again」把含密码的完整命令明文写入设置文件,公开 GitHub 扫出 1,379 个密钥

November 8, 2026

把数据库密码直接敲进一条命令,再在 Claude Code 的批准弹窗里选下「Yes, and don't ask again」——安全公司 Apiiro 的一项研究显示,这串再普通不过的操作会让密码以明文留在项目文件夹里。据 2026 年 11 月 8 日报道,这个由 Anthropic 开发的编程代理(coding agent)在开发者以该选项批准一条精确命令时,会把完整命令原样写入项目的 .claude/settings.local.json,用户敲进命令里的数据库密码或 token(令牌)也一并存入。 在 11 月 7 日转述了同一研究。

Apiiro 给出的量级是:扫描公开 GitHub 上 103,617 个仓库,找到 104,185 份该文件的副本,其中 1,122 份(约 1.1%)至少含有一个密钥,合计 1,379 个不同密钥,属于 63 家组织,其中多数是软件公司。数字出自 。一个后果已经得到直接确认:Apiiro 本周早些时候通知的一家公司核实后,发现自家密钥仍然有效。研究人员称,最严重的案例包括一家数据库厂商自己的管理员级(admin-level)云密钥,和一个病历数据库的所有者(owner)密码。

「Yes, and don't ask again」如何把密码写进设置文件

按 Anthropic 官方 的描述,Bash 命令默认需要人工批准;弹窗里的第二个选项写的是「Yes, and don't ask again for:」加上具体内容,选中后规则按仓库和命令永久生效,保存到 git 仓库根目录的 .claude/settings.local.json,之后匹配的命令不再询问、直接执行。文档同时写明:保存的规则只覆盖选项点名的内容,不带通配符的规则只匹配那一条精确命令。

The Hacker News 的报道解释了问题出在哪里:弹窗有时给的是一个模式(比如 npm test *),有时给的是一条精确命令;当它是精确命令时,用户敲在命令里的密码或 token 也会被一并明文存下。Apiiro 研究人员用 Claude Opus 5.5 和 Fable 5.1 复现了这一行为,并称在对比文档的 16 个编程代理中,Claude Code 是唯一被确认默认把完整已批准命令存进项目文件的。

防线只在一台开发机上,管不住 .gitignore 和已提交的历史

Claude Code 并非没有防护。Anthropic 的 写道:第一次在 git 仓库里写这个文件时,Claude Code 会把 **/.claude/settings.local.json 加入用户的全局 git excludes(即 core.excludesFile,默认为 ~/.config/git/ignore),使其不进这台机器上的任何提交。

Apiiro 指出,这道防线有三个盲区:它只存在于一名开发者的机器配置里;Claude Code 不会把文件写进项目自己的 .gitignore,所以保护不随项目走,换一台机器就失效;对已经提交过的文件,它无能为力。文档自己也提醒:如果文件是手动创建的,得自己把它加进 .gitignore。

研究人员追踪的 1,105 个仓库中,有 539 个出现过一条把 Claude 列为共同作者(co-author)的提交改动这个文件;他们由此推断,Claude 经常自己把文件提交进仓库。

一半仓库的密钥已暴露至少 217 天,历史提交里还藏着 734 个

按 The Hacker News 转述的判定标准,一个值要被算作密钥,需要匹配已知密钥格式,或者密码、token 旁边跟着一台公网服务器的地址,并由一名 AI 审核员确认。在当前文件里找到的 1,379 个密钥中,有 379 个数据库密码、43 组可登录公共服务器的 SSH 凭据、42 个 GitHub、GitLab 和 npm 的 token、23 个 AWS 密钥;The Hacker News 称,超过三分之一的密钥能直接连上数据库。

截至 11 月 2 日(周一),每一份含密钥的文件仍然在其仓库的默认分支上;在一半受影响仓库里,它已经在那里至少 217 天。历史提交里还有 734 个密钥、分布在 509 个仓库,多数因为文件后来被删除而不在当前副本中;74 个仓库的 211 个 fork(复刻仓库)也带着同样的凭据。把历史提交、团队有意提交的共享文件 .claude/settings.json(76,011 份副本中 298 份含密钥,多数藏在 allow(允许)规则里)和保存下来的 agent 聊天日志一并计入,总数达到 2,539 个密钥、分布在 1,994 个仓库。

上述数字均出自 Apiiro 自家研究口径,目前没有独立方复核。

gitleaks 和 TruffleHog 漏掉了 215 份含密文件

通用的密钥扫描器只接住了一部分。Apiiro 在关闭工具自身验证步骤的情况下,把 gitleaks 和 TruffleHog 跑遍全部副本:1,122 份含密文件中,gitleaks 标出 564 份,TruffleHog 标出 643 份,有 215 份两个工具都没有发现。

漏报的原因和命令本身有关:扫描器寻找的是已知密钥格式,而 PGPASSWORD=、sshpass -p、mysql -p 后面跟着的密码,在命令行里看上去就是一个普通单词。

提交于 2025 年 8 月的 bug 报告,被机器人以 not planned 关闭

这不是第一次有人报告该行为。2025 年 8 月 11 日,用户 asherfeldmangit 在 anthropics/claude-code 仓库提交 ,标题就写明「approved bash commands containing credentials are stored as is with plain text credentials in settings.local.json」,正文指出凭据未经脱敏就进入自动批准的 permissions.allow 数组。

在机器人先后发出 30 天、60 天无活动警告后,这份报告于 2026 年 1 月 3 日被自动关闭;据 The Hacker News 和 AI Chat Daily 转述,关闭原因标记为 not planned(不作计划)。Apiiro 引用的另外四份相关报告,截至 11 月 7 日也全部被同一个机器人关闭,最近一份在报道前一天被关闭;研究人员称,这些报告没有一份得到过 Anthropic 的回复。

Apiiro 的处置清单:先换密钥,再清理文件

Apiiro 给开发者的处置顺序很明确:先轮换,再清理,因为删除文件并不能撤销泄露——旧版本仍留在 git 历史和 fork 里。具体步骤包括:搜索仓库和 git 历史中的 .claude/settings.local.json 与 .claude/settings.json,文件已经删掉的也要查;用 git rm --cached 停止跟踪本地文件并加入项目自己的 .gitignore;打开本机文件,删掉每条含密钥的规则;把密钥改成从 secrets manager(密钥管理服务)引用的变量(如 $DB_URL),让保存的规则里只有变量名;批准命令模式(如 Bash(npm run:*))而不是单条命令。

给安全团队的建议是:把 .claude/、.cursor/、.gemini/、.specstory/ 这些 agent 目录当成 .env 文件对待,加入组织的 .gitignore 模板;让 pre-commit(提交前检查)和 CI(持续集成)的密钥扫描覆盖 git 历史,并能识别命令中的密码;优先核查能登录公网服务器的凭据。

不进入 GitHub 的副本同样有风险:这只是项目文件夹里的一个普通 JSON 文件,也可能被打进 npm 包、Docker 镜像、zip 压缩包或同步盘。The Hacker News 提到,恶意软件早已盯上开发者机器——2025 年 9 月的 Shai-Hulud 蠕虫就曾在受感染电脑上运行 TruffleHog 搜刮密钥。

这项研究留下的缺口是:除了一家自行核实密钥仍有效的公司,Apiiro 没有测试其余密钥是否还能用,也没有说明是否发现密钥被人使用过的迹象;两篇报道中均未提及 Anthropic 对研究结果本身的回应。

参考链接

More from this developing story

  • Apiiro 报告:Claude Code「Yes, and don't ask again」把含密码的完整命令明文写入设置文件,公开 GitHub 扫出 1,379 个密钥Nov 8, 2026
  • GitGuardian 独立复核 Claude Code 密钥泄露:公开 GitHub 23,276 个仓库含 31,088 个密钥、17% 检测时仍有效,Docker Hub 镜像另涉 613 个Nov 9, 2026