今天是愚人节,但这篇文章不是玩笑。
我看了一天 Claude Code "泄露"的报道 — VentureBeat、Fortune、Gizmodo、The Register、Hacker News。512,000 行代码!Feature flags!System prompts!一个净室 Rust 重写版本(为了规避 DMCA)在不到一天内就拿到了 10 万 GitHub star — 创下了世界纪录。现在已经 11 万,还在继续增长。
他们都搞错了。这些内容早就是公开的。就在 npm 上。明文存放。已经好几年了。现在就打开 unpkg.com/@anthropic-ai/claude-code/cli.js — 那就是整个 Claude Code CLI,点一下就能在浏览器里阅读。根本不需要什么泄露。
所谓"泄露"的是一个 source map 文件,它只是在一份本来就毫无保护的代码之上添加了内部开发者注释和目录/源码结构。
到底发生了什么
一个 .map source map 文件 — 原本用于内部调试 — 被意外包含在了 npm 上 @anthropic-ai/claude-code 包的 2.1.88 版本中。安全研究员 Chaofan Shou 发现了它,在 X 上发帖,然后互联网做了剩下的事。
Anthropic 确认了这个失误:"这是一个由人为错误导致的发布打包问题,而非安全漏洞。" 该包随后被撤下,但那时它已经被到处镜像了。
有趣的是?这已经是第二次了。 一次几乎一模一样的 source map 泄露发生在 2025 年 2 月。同一个产品,同样的失误,相隔十三个月。
24 小时内发生了什么
接下来发生的事真的令人印象深刻。在一天之内:
-
代码转储出现在 GitHub 上 — 比如 nirholas/claude-code,它在几小时内就被 Anthropic 发起 DMCA 下架,但在那之前已经被 fork 了数百次。
-
Claw Code — Claude Code 架构的完整 Rust 重写版 — 在 2 小时内达到了 50,000 GitHub star,成为历史上最快达到这一里程碑的仓库。目前正在被积极开发为一个开源 AI 编程 agent 框架。
-
ccleaks.com 横空出世 — 一个设计精良的分析网站,列出了在源码中发现的每一个未发布功能、隐藏命令和构建标志。还配有可分享的卡片,展示了 "BUDDY"(AI 伴侣宠物)、"ULTRAPLAN"(30 分钟远程规划模式)和其他 44 个 feature flags 等发现:
- 数十篇分析文章出现在 DEV Community、YouTube 和各大技术博客上,逐一剖析每个细节。
所有这一切,都发生在一天之内。AI 时代的软件行业真的太疯狂了。
但代码本来就在那里
大多数报道都忽略了一个事实:Claude Code 是以单个打包 JavaScript 文件的形式发布的 — cli.js — 通过 npm 分发。13MB,16,824 行 JavaScript。自产品发布以来,它就一直公开在那里,任何人都可以访问。
我们在 AfterPack 分析了这个文件,作为一个反混淆案例研究。我们的发现:它只是被压缩了,并没有被混淆。
两者的区别在这里。压缩(minification)— 每个打包工具(esbuild、Webpack、Rollup)默认都会做的事 — 缩短变量名并移除空白字符。它让代码体积更小,便于分发。它从来就不是用来隐藏任何东西的。
混淆(obfuscation)则加密字符串、扁平化控制流、注入死代码、添加防篡改机制。它的目的是让逆向工程在计算上变得极为昂贵。
Claude Code 只有前者,后者一个都没有。
| 技术 | 是否存在? |
|---|---|
| 变量名混淆 | 是(标准压缩) |
| 空白字符移除 | 是(标准压缩) |
| 字符串加密/编码 | 否 |
| 控制流扁平化 | 否 |
| 死代码注入 | 否 |
| 自我防御/防篡改 | 否 |
| 字符串数组旋转 | 否 |
| 属性名混淆 | 否 |
全部 148,000 多个字符串字面量都以明文形式存在。 每一条 system prompt、每一个工具描述、每一条行为指令 — 就在 JavaScript 里,用文本编辑器就能读。根本不需要 source map。
我们让 Claude 对自己进行反混淆
接下来才是真正有意思的地方。我们不需要 source map 就能提取 Claude Code 的内部实现。我们让 Claude — Anthropic 自己的模型 — 来分析和反混淆压缩后的 cli.js 文件。
效果非常好。
使用一个简单的基于 AST 的提取脚本,我们在 1.47 秒内解析了整个 13MB 文件,提取出了 147,992 个字符串。分类后:
- 1,017 条 system prompts 和指令
- 431 个工具描述
- 837 个唯一的遥测事件名称(全部以
tengu_为前缀 — Claude Code 的内部代号) - 504 个控制产品行为的环境变量
- 3,196 条错误消息
- 硬编码的 endpoints、OAuth URLs、一个 DataDog API key、完整的模型目录
每一个字符串。不到 2 秒全部提取完毕。无需解密。无需反混淆。只是解析而已。
而且不只有我们发现了这一点。Geoffrey Huntley 在这次泄露事件的数月之前就发布了 Claude Code 的完整"净室转译"— 使用 LLM 将压缩后的 JavaScript 转换为可读的、结构化的 TypeScript。他的核心洞察是:"LLM 在反混淆、转译和结构到结构的转换方面表现得好到惊人。"
Source map 并没有揭露代码。代码本来就已经暴露了。Source map 只是在上面加了注释和源码树结构。
Source Map 实际增加了什么
公平地说 — source map 确实揭示了一些真正敏感的信息,这些信息从压缩后的 bundle 中不容易提取:
内部代码注释。 开发者笔记、TODO、决策理由。那种你写的时候只期望队友能看到的东西。
精确的文件结构。 完整的 1,884 个文件的项目目录树,包含原始文件名、模块边界和依赖关系。
带代号的 Feature flags。 像 tengu_amber_flint、tengu_cobalt_frost 和 tengu_miraculo_the_bard 这样的名称 — 这些内部实验名称揭示了产品策略和 A/B 测试结构。
隐身模式。 一个功能,当 Claude Code 在非 Anthropic 仓库中使用时,会剥离内部代号和引用 — 这样模型就不会在公开场合意外说出 "Tengu" 或 "Capybara"。
KAIROS。 一个未发布的自主守护进程模式 — 带有 cron 周期和 GitHub webhook 订阅的后台 agent worker。
反蒸馏机制。 Claude Code 在 API 请求中发送 anti_distillation: ['fake_tools'],将虚假的工具定义注入到 prompt 中,以便在有人录制 API 流量来训练竞争模型时污染训练数据。
这些确实敏感。内部注释的暴露是真实的。但实际的源码逻辑 — prompt、工具、架构、endpoints — 这些都早就在 cli.js 里了。一直都在。
这种事比你想的更常见
可能会让你意外的是:这不是 Anthropic 独有的问题。这是整个行业普遍接受的做法。
我们在GitHub 自己的网站上运行了 AfterPack 安全扫描器 — 这可是世界上最顶尖的工程组织之一。以下是我们的发现:
电子邮件地址。环境变量名称。内部 URL。 全都在生产环境的 JavaScript 和 source map 中,公开可访问。你可以自行查看完整扫描结果。
而 Anthropic 自己的网站 — claude.ai — 也有同样的问题。他们在 s-cdn.anthropic.com/s.js 上的生产环境 JavaScript 暴露了员工电子邮件地址:
没有人谈论这些。VentureBeat 不会写一篇关于 GitHub 在 JS bundle 中暴露邮箱地址的头条新闻。Hacker News 也不会有关于 Anthropic CDN 脚本暴露内部 URL 的讨论帖。但这本质上是完全一样的问题 — 生产环境的 JavaScript 暴露了本不该公开的信息。
你现在就可以检查自己的网站:afterpack.dev/security-scanner,或者在终端中运行:
| npx afterpack audit https://your-site.com |
为什么 AI 改变了整个局面
以下是 Claude Code 泄露事件所揭示的现实 — 即使这不是大多数人关注的叙事:
压缩从来都不是安全措施。 它只是体积优化。对人类读者来说有一定阻碍作用的变量重命名,对 LLM 来说不值一提。AI 读压缩代码就像你读格式化代码一样轻松。
System prompts 是新的商业机密。 公司花数月时间精心设计塑造产品行为的 prompt。Anthropic 的 Claude Code prompts — 那些 "# Doing tasks"、"# Executing actions with care"、"# Tone and style" 章节 — 代表着严肃的 prompt engineering 工作。全部以明文形式随 JavaScript 发布。
遥测名称泄露了产品路线图。 我们提取的 837 个 tengu_* 事件精确地告诉你 Anthropic 正在构建、测试和衡量什么。像 tengu_desktop_upsell_shown 和 tengu_review_overage_dialog_shown 这样的事件名称暴露了变现策略。
环境变量暴露了你还没准备好发布的东西。 504 个描述性环境变量名 — CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS、CLAUDE_CODE_DISABLE_AUTO_MEMORY、MAX_THINKING_TOKENS — 揭示了尚未经过生产环境验证的早期功能和实验性 endpoints。对攻击者来说,这是一份通往测试最少、最脆弱攻击面的路线图。对竞争对手来说,这是你的整个功能管线。对用户来说,这是一份他们本不该知道的配置清单。
而这不仅仅关乎 Anthropic。每一个 JavaScript 应用 — React 前端、Electron 桌面应用、React Native 移动应用、Node.js CLI — 发布的代码现在都能被 AI 阅读、分析、重构和模仿。带有 feature flags 的支付网关。包含定价逻辑的 SaaS 产品。带有硬编码 endpoints 的认证流程。
我们正在准备一份完整的研究,评估 AI 模型逆向工程流行 JavaScript 混淆器的能力 — 不仅是压缩后的代码,还包括被刻意保护过的代码。Claude Code(由 Opus 驱动)目前是推理和代码任务上最强的模型,而它在这方面的能力令人警觉。关注我们,别错过这篇报告:
当前"保护"手段的问题
关键在这里。你刚刚读完的文章证明了压缩不是保护。但大多数人没有意识到的是:传统混淆也不再是了。
每一个现有的 JavaScript 混淆器都是在 Opus 4.6 出现之前构建的。它们的技术 — 字符串加密、控制流扁平化、死代码注入 — 都是顺序的、可逆的变换。每一步都有逆操作。在数百万代码样本上训练的 AI 模型可以识别并撤销这些模式,通常只需几秒。
把设置调到最高,确实可以减慢分析速度 — 但代价是代码体积膨胀 10 倍和严重的性能下降。到那时候,你为了防止代码被阅读,已经把应用搞得无法正常使用了。
这正是 AfterPack 要解决的问题。
我为什么在做 AfterPack
2026 年 9 月修订:本节早先的版本声称这些变换是不可逆的。按当时的表述这是错误的;本节现在描述的是设计实际做了什么。2026 年 10 月再次修订:从运行中的构建读到的值依然是读到了,所以本节现在只说针对某次构建形态编写的工具会失效。
AfterPack 采用了不同的思路。传统混淆器组合的是一组固定的变换,所以每次构建都有同样可识别的结构,写一次的解码器对所有构建都有效。AfterPack 每次构建都会抽取新的种子,所以每次构建的形态都不同,针对某次构建的模式编写的工具到下一次就会失效。运行你代码的人仍然能读到它用到的值;逆向仍然可能,就像任何在客户端运行的东西一样。
核心思想:不只是让代码难读一次,而是让工具无法复用。针对上周构建编写的脚本、补丁和识别器在本周的构建上不再有效,这份投入会随着你的发布节奏而失效。
当然,你仍然可以调试自己的代码。AfterPack 会生成 source map,把混淆后的输出映射回你的原始源码。构建对读者不可读,对你不是。
使用 Rust 构建以保证速度 — 快到可以在每次构建、每次提交时运行,甚至在 Cloudflare Workers 边缘上也能运行。免费版足够慷慨,让你没有理由不用。
当前的现状 — 一家市值 600 亿美元以上的 AI 公司仅凭打包工具的压缩就发布了最敏感的客户端代码 — 不会持续太久。我做 AfterPack 是因为我认为保护应该成为每个构建流程的默认步骤,而不是事后才想到的。如果你感兴趣,可以先在你自己的网站上试试扫描器 — 你可能会对暴露的内容感到惊讶。
