当前位置:首页 > 编程开发 > 正文

Claude Code 凭据泄露 1122 例,怎么自查

约 3763 字 · 预计阅读 10 分钟
一句话总结:Claude Code 会把用户批准过的 shell 命令逐字存进本地 .claude.json,误提交到公开仓库就泄露真实凭据,研究人员在 GitHub 上确认了 1,122 个案例。我照着这个模式写了个扫描器:20 个真泄露抓到 14 个,12 个安全样本零误报,但两个看似无害的正则写法各吃掉了一类泄露。

11 月 9 日,安全厂商 Apiiro 公布了这个发现。11 月 10 日发布的 Claude Code 2.1.321 修了一批权限和凭据泄漏问题,包括 MCP 的 OAuth 那部分。

Claude Code 凭据泄露是怎么发生的

Claude Code 为了减少重复询问,会把用户批准过的命令记在本地配置里,下次遇到同样的命令就直接执行,不再问。

问题在于记的是原文。一个批准过的命令如果是 export DB_PASSWORD=Pr0d_2026!x,那这一行就原样落在 JSON 里。

.claude.json 通常放在项目根目录或用户目录。前者很容易被 git add . 带进去——很多人没有把这个文件名写进 .gitignore,因为它看起来不像配置文件,更像编辑器缓存。

Apiiro 在公开的 GitHub 文件里数出 1,122 个真实凭据。

凭据泄露扫描器实测:20 个抓到 14 个

我按这个模式造了 32 个样本:20 个真泄露(8 种写法,覆盖 password、API key、token、client_secret、JWT),12 个安全样本(读环境变量、空字符串、占位符、提示输入)。

核心规则一条:键名像凭据 + 赋值了一个双引号字符串。

RULE = re.compile(
    r'(?i)\b(password|passwd|pwd|secret|secret_key|api[_-]?key|apikey'
    r'|token|access_token|auth_token|client_secret)\b'
    r'\s*[:=]\s*["\']([^"\']{6,})["\']'
)
PLACEHOLDER = re.compile(r'(?i)^(x+|\*+|changeme|your|example|test|demo|password|null|none|<.*>|\$\{.*\})')

结果:

实际是泄露 实际安全
判定为泄露140
判定为安全612

准确率 81.2%,精确率 100%,召回率 70%。零误报是我把占位符黑名单写得很宽换来的,代价就是漏报。

Claude Code 凭据泄露 1122 例,怎么自查

图 1:32 个样本上的判定结果,漏报集中在两类写法

两个 bug:一个吃掉 X 开头的密码,一个让带前缀的键名溜过去

漏掉的 6 个里,5 个能归到两个原因。

第一个:^x+ 把 X 开头的密码当成占位符。

占位符黑名单里我写了 x+,本意是过滤 "xxxxxxxx" 这种假密码。但正则的 x+ 匹配"一个或多个 x",^x+ 只要开头是 x 就算命中。于是 password = "Xk9#mP2$vL7q" 被判定为占位符直接跳过——这个密码强度还挺高的,恰恰因为首字母是 X 逃过一劫。

正确写法要加长度约束:^x{6,}$,要求整串都是 x。

第二个:\b 在 db_password 上不成立。

正则里的 \bpassword\b 要求词边界。但下划线属于单词字符,db_password 里 _ 和 p 之间没有边界,所以匹配失败。同理 DB_PASS、MY_SECRET 这些带前缀的键名全部漏掉。

改法是去掉前导 \b,或者在键名前面允许下划线:(?<![a-z0-9])password(允许前面是下划线,不允许前面是字母数字)。

这类 bug 有个共同特点:写的时候觉得"规则已经很全了",跑完发现漏的都是最常见的写法。

凭据泄露自查:文件名规则比内容规则更有效

同一批样本,如果只按文件名筛——.claude 目录、*.env、config*——20 个真泄露全都能捞到,一个不漏。

这个结果不奇怪。凭据泄露的载体比凭据本身更稳定:不管里面写的是 password 还是 token,文件名和路径就那么几种。

所以实际做防护,顺序应该反过来:

先管住目录,把 .claude/、.claude.json、.env*、*.pem 写进 .gitignore,再加一条 pre-commit 钩子拦住这类文件。这一步的成本接近零,覆盖率最高。

再管内容,用正则兜底,用来抓那些被重命名、或者塞进 notes.txt 里的凭据。这一步必然有漏报,别指望它。

最后做回溯,如果这些文件已经被提交过,光删文件没用,git 历史里还在。要用 git filter-repo 清历史,然后立刻轮换所有可能泄露的凭据。轮换是必须的,清理历史只是止损。

agent 的记忆正在变成新的攻击面

同一批研究还提到另一个方向的漏洞:提示注入可以诱导 agent 取回被明确要求删除的数据,绕过零信任架构里设好的清除检查点。

两件事指向同一个结论:agent 的"记忆"和"批准记录"正在成为新的凭据攻击面,而这部分能力通常是在追求自动化流畅度的过程中被顺手打开的。

设计 agent 的时候有个默认值值得先定下来:本地状态目录里到底允不允许存明文?如果允许,那它必须被当作凭据对待——不进版本控制、不随项目分发、有轮换机制。之前拆 Ollama 的仓库结构时也遇到过类似的问题:模型文件按哈希命名,删了 manifest 之后 blob 还留在磁盘上,占着几十 GB 没人知道。

上生产之前,花五分钟检查一下项目里有没有 .claude 之类的目录已经进了版本控制。文件头部的元信息怎么读是另一套技能,但道理一样:先看清楚文件里到底存了什么,再决定能不能公开。

参考资料

  1. AI 行业快讯 2026-11-10:Claude Code 把"别再问"写成了明文密码
目录导航
  • Claude Code 凭据泄露是怎么发生的
  • 凭据泄露扫描器实测:20 个抓到 14 个
  • 两个 bug:一个吃掉 X 开头的密码,一个让带前缀的键名溜过去
  • 凭据泄露自查:文件名规则比内容规则更有效
  • agent 的记忆正在变成新的攻击面
    • 参考资料
  • 相关文章:

  • 规则工程:给 AI 编程工具写一份新员工手册,AGENTS.md 从入门到不翻车
  • AI 编程工具算账:同一份需求,月成本从 0 到 200 美元差在哪
  • AI 编程工具怎么选:先过滤硬约束,再对齐用量形态,最后才是看榜单
  • 海外 AI 编程工具横评:Cursor、Claude Code、Copilot 该选谁,先看它们怎么收钱
  • 发表评论

    ◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。