你让 Claude Code 连一次数据库。它拼出一条命令,密码就写在命令里。你不想每跑一次都点一次允许,于是选了「是,且不再询问」。这一下,密码的命运变了。
它没有“记住密码”。它记住的是你批准的这条命令。Claude Code 会把这次授权写成一条 allow 规则,存进项目目录的 `.claude/settings.local.json`;规则要匹配以后同样的调用,最直接的办法就是保存命令原文。于是数据库口令、API token、SSH 密码,跟着命令一起,从一次性的终端输入,变成了项目里的一行配置。微博
所以,埋下隐患的不是模型的记忆力,是权限系统里那个叫「不再询问」的开关。
问题在于,这个文件在项目里,保护却在机器上。Apiiro 的研究说,Claude Code 只把它加进这台机器的全局 git 忽略,不写进仓库自己的 `.gitignore`。换一台机器、开一个容器、把项目文件夹整个拷过去,或者文件已经被提交过,它就会像普通文件一样进仓库。名字里的 “local” 拦不住 `git add`。Hacker News
11 月 9 日,Ars Technica 的报道把这件事推到台前。 这不是几台机器上的偶发事故。Apiiro 11 月 5 日发布的研究扫了 GitHub 上 104,185 份公开的 `.claude/settings.local.json`,其中 1,122 份的当前副本里能找到密钥;把历史提交、共享配置和 agent 对话记录算进去,是 1,994 个仓库里的 2,539 条凭据,涉及 63 家组织。 这些文件在默认分支上停留时间的中位数是 217 天,不是刚上传就被发现的意外。IT之家微博
GitGuardian 把时间拉长到 2025 年 1 月至 2026 年 11 月 7 日,看到 31,088 条不同的密钥曾被推上公开仓库,其中 5,343 条在检出时仍然有效。GitGuardian
「用户自己手滑提交」解释不了全部。Apiiro 追踪的 1,105 个含密仓库里,539 个仓库的改动提交带 Claude 的 co-author 署名;GitGuardian 也看到 263 个仓库的泄露提交,作者邮箱是 Claude 的 noreply 地址。工具参与了把文件送进仓库的动作。微博
Anthropic 的 Claude Code 负责人 Boris Cherny 在 Hacker News 上回应说,这个文件本来就该留在本地,Claude 创建它时会自动 gitignore,所以泄露的副本多半是用户手动创建并提交的。这个解释有道理:文件确实不该进仓库。但它覆盖不了全部。GitGuardian 抽查了约 3,000 处密钥,能定位的全部落在 allow 规则或环境变量块里,63% 是密码、令牌这类没有厂商格式的字符串——这更像权限提示写出来的东西,而不是手写的配置文件。GitGuardian
团队说正在试自动模式和内置密钥扫描,还没给时间表。Hacker News
要补救,顺序不能反。先轮换文件里出现过的每一把钥匙,再清理仓库:历史和 fork 里还有副本,删文件不够;用 `git rm --cached` 停止跟踪,把路径写进仓库自己的 `.gitignore` 和 `.dockerignore`;以后在命令里用 `$DB_URL` 这样的变量,让规则存变量名,不存值;授权尽量用窄前缀,别批准整条带密文的命令。
但这些是用户侧的止损。真正的隐患在设计里:一个要“记住批准”的权限系统,只要记的是命令原文,就迟早会记住命令里的秘密。更稳的方向是会话级授权,或者在保存规则前去掉命令里的秘密,只留可匹配的骨架。
在那之前,最该记住的是:你点的不是“记住密码”,是“记住这条命令”。密码只是恰好在那条命令里。