AI Pulse

Claude Code 的「不再询问」,让 1,122 份公开仓库文件存着密钥

发生了什么

GitLab 几天前发文提到了这件事,但那个数字值得重复。Apiiro 在公共仓库中发现了 104,185 份 .claude/settings.local.json,其中 1,122 份含有密钥。那么密钥是怎么进到这个文件里的?

密钥为什么会出现在这个文件里

当你以“Yes, and don't ask again”批准一条 shell 命令时,Claude Code 会把那条确切的命令记录到 permissions.allow 中,存进 .claude/settings.local.json,从而以后不再就这条命令询问你。如果你在命令里敲过 token 或密码,现在它们就以明文被保存在文件中了。

为什么会泄漏到公共仓库

原因有一点微妙。Claude Code 会通过把你个人全局的 git excludes(全局排除规则)中加入该文件,从而使它不被 Git 跟踪;但这些全局规则只存在于你自己的机器上。项目的 .gitignore 默认不会列出这个文件。于是,当仓库被共享或有人克隆时,这个文件就可能被一台从未有过该排除规则的机器提交并推送到远端。

如果你在仓库里发现了这个文件

请做两件事:

1. 轮换密钥,而不是只删除那一行。一旦该文件被推送过,值就已经进入 Git 历史。因此,只删除当前提交中的条目并不会消除风险,必须去密钥提供方(如云服务商)轮换(即作废并重新生成)该密钥。
2. 意识到这不是 Claude Code 独有的问题。任何实现了“不再询问”记忆功能的 agent 都会保留类似的文件。Cursor、Copilot、Gemini 等工具都有相同模式。因此,请把检查范围扩大到所有 agent。

手动快速检查

在仓库中搜索 .claude/settings.local.json,确认它已被加入项目的 .gitignore(而不是只存在于你的全局排除中),并逐条查看权限条目里是否有看起来像 token 的字符串。

使用自动化工具检查

本人维护一个名为 cfgaudit 的开源小工具,专门跨不同 agent 检查两类问题:

- 权限条目中是否存在硬编码的密钥;
- 该文件是否未被 gitignore。

它可以作为 pre-commit 钩子、CI 步骤或一次性扫描运行。详细说明和仓库地址:

- 说明: https://cfgaudit.github.io/blog/claude-code-dont-ask-again-secret-leak/
- 仓库: https://github.com/cfgaudit/cfgaudit

> 披露:本人是 cfgaudit 的维护者。你检查过自己的仓库里有没有这个文件吗?

社区高票评论摘录

> +53 u/Illustrious-Bet-1368:并不是什么秘密,如果你把密钥明文贴到聊天里。而且为什么要通过聊天分享密钥?Claude 还会在你每次 cd 时创建空的隐藏文件夹(如果不用绝对路径或没调整设置)。空文件夹不会被 git 跟踪,所以只是杂乱而已。建议给每个 gitignore 加上 .claude,问题解决。另外,别再往聊天里粘贴密钥和密码了。

> +23 u/Zolty:使用密码管理器并配置好它的 CLI,再创建一个 Claude skill 来指示如何在命令运行时通过 CLI 把密钥喂给命令。

> +10 u/Aareon:在把 vibe coding 项目公开之前,难道不做一点信息安全检查?每个人都应该使用 gitleaks,并且为你在用的 token 和 key 写匹配规则。别忘了在公开之前轮换所有密钥,以防它们已经出现在 git 历史里。

> +7 u/TeamTomorrow:不管你怎么看这篇文章,如果你用 Claude Code,今晚就值得做这些修复:把 .claude/settings.local.json 加入全局 gitignore,检查它是否曾被提交(git log --all -- .claude/settings.local.json),并轮换任何出现在被批准命令中的密钥。在新的提交里删除文件并不能把它从历史中移除。

阅读原文
📚 相关主题 安全开源

订阅 AI Pulse

每天 08:00 · 12:30 · 18:30 · 23:50 更新