這不是愚人節的玩笑。
我一整天都在關注 Claude Code「外洩」的報導——VentureBeat、Fortune、Gizmodo、The Register、Hacker News。512,000 行程式碼!功能旗標!系統提示!為了規避 DMCA 而進行的乾淨室(clean-room)Rust 重寫,在不到一天內就獲得了 10 萬個 GitHub 星標,創下世界紀錄。現在已達 11 萬,而且還在增加。
這些報導都有點錯誤。那些程式碼早已公開。在 npm 上。以純文字形式。而且已經公開多年。現在就打開 unpkg.com/@anthropic-ai/claude-code/cli.js 看看——那就是整個 Claude Code CLI,點擊一下即可看到,可在瀏覽器中閱讀。根本不需要外洩。
所謂的「外洩」,其實是一個原始碼對映檔案(source map file),它在從未被保護過的程式碼之上添加了內部開發者註解,再加上一個目錄/原始碼結構。
一個 .map 原始碼對映檔案——用於內部除錯——意外地被包含在 npm 上的 @anthropic-ai/claude-code 套件的 2.1.88 版本中。安全研究員 Shou Chaofan 在 X 上發現了它並發布,然後網際網路就接管了一切。
Anthropic 確認了這個錯誤:「這是由人為錯誤造成的發布打包問題,而非安全漏洞。」該套件已被移除,但當時它已經被鏡像到各處。
有趣的是?這是第二次了。在 2025 年 2 月發生了幾乎相同的原始碼對映檔案外洩事件。同一個產品,同樣的錯誤,間隔十三個月。
接下來發生的事情確實令人印象深刻。在一天之內:
GitHub 上出現了程式碼轉儲——例如 nirholas/claude-code,該儲存庫在數小時內就被 Anthropic 以 DMCA 移除,但在此之前已被分支數百次。
Claw Code——Claude Code 架構的完整 Rust 重寫——在 2 小時內獲得了 5 萬個 GitHub 星標,成為歷史上最快達到此里程碑的儲存庫。它現在正作為一個開源 AI 編碼代理框架積極開發中。
ccleaks.com 上線了——一個設計完善的分析網站,記錄了原始碼中發現的每一個未發布功能、隱藏命令和建置旗標。並附有可分享的卡片,介紹了「BUDDY」(一個 AI 伴侶寵物)、「ULTRAPLAN」(30 分鐘遠端規劃模式)以及其他 44 個功能旗標:
這一切。都在一天之內發生。在 AI 時代,軟體變得越來越瘋狂。
大多數報導都忽略了顯而易見的事實:Claude Code 以單一的捆綁 JavaScript 檔案——cli.js——透過 npm 發布。它有 13MB,16,824 行 JavaScript。而且自產品推出以來,它就一直公開可得。
我們在 AfterPack 對這個檔案進行了分析,作為一個去混淆(deobfuscation)案例研究。我們發現:它是最小化(minified),而不是混淆(obfuscated)。
兩者之間的區別很重要。最小化——這是每個 bundler(esbuild、Webpack、Rollup)預設執行的操作——會縮短變數名稱並移除空白字元。它使程式碼在發布時更小。它從未被設計來隱藏任何東西。
混淆會加密字串、扁平化控制流程、注入死程式碼、添加反篡改機制。它旨在使逆向工程在計算上變得昂貴。
Claude Code 只有前者。後者則完全沒有。
所有 148,000 多個字串字面量都以純文字形式存在。每一個系統提示、每一個工具描述、每一個行為指令——都直接存在於 JavaScript 中,可以用文字編輯器讀取。無需原始碼對映檔案。
我們不需要原始碼對映檔案來提取 Claude Code 的內部資訊。我們詢問了 Claude——Anthropic 自家的模型——來分析和去混淆最小化的 cli.js 檔案。
使用一個簡單的基於 AST 的提取腳本,我們在 1.47 秒內解析了完整的 13MB 檔案,並提取了 147,992 個字串——超過 1,000 個系統提示、837 個遙測事件(均以 tengu_ 開頭,這是 Claude Code 的內部代號)、504 個環境變數、3,196 個錯誤訊息、硬編碼的端點、OAuth URL、一個 DataDog API 金鑰,以及完整的模型目錄。每一個都以純文字形式存在。無需解密。無需去混淆。只是解析。
而且我們不是唯一發現這一點的人。Geoffrey Huntley 在這次外洩前幾個月就發布了 Claude Code 的完整「乾淨室轉譯」(cleanroom transpilation)——使用 LLM 將最小化的 JavaScript 轉換為可讀的結構化 TypeScript。他的關鍵見解是:「LLM 在去混淆、轉譯和結構到結構的轉換方面非常出色。」
原始碼對映檔案並沒有揭露程式碼。程式碼早已被揭露。原始碼對映檔案只是在上面添加了註解和原始碼樹結構。
公平地說——原始碼對映檔案確實揭露了一些從最小化捆綁包中不易提取的真正敏感資訊:
內部程式碼註解。開發者筆記、待辦事項、決策的理由。那種你寫的時候只期望隊友閱讀的東西。
確切的檔案結構。完整的 1,884 個檔案專案樹,包含原始檔名、模組邊界和依賴關係。
帶有代號的功能旗標。諸如 tengu_amber_flint、tengu_cobalt_frost 和 tengu_miraculo_the_bard 等名稱——內部實驗名稱,揭示了產品策略和 A/B 測試結構。
隱蔽模式(Undercover mode)。一個功能,當 Claude Code 在非 Anthropic 的儲存庫中使用時,會移除內部代號和參考——這樣模型就不會意外地在公開場合說出「Tengu」或「Capybara」。
反蒸餾機制(Anti-distillation mechanisms)。Claude Code 在 API 請求中發送 anti_distillation: ['fake_tools'],在提示中注入誘餌工具定義,以在有人記錄 API 流量來訓練競爭模型時毒化訓練資料。
這些是敏感的。內部註解確實是真正的暴露。但實際的原始碼邏輯——提示、工具、架構、端點——都已經存在於 cli.js 中。一直都是。
這不是 Anthropic 特有的問題。這是業界普遍採用的做法。
我們在 GitHub 的網站上運行了 AfterPack 的安全掃描器——這是世界上最複雜的工程組織之一:
電子郵件地址。環境變數名稱。內部 URL。都存在於生產環境的 JavaScript 和原始碼對映檔案中,公開可得。請自行查看完整的掃描結果。
Anthropic 自家的網站——claude.ai——也存在同樣的問題。他們在 s-cdn.anthropic.com/s.js 上的生產環境 JavaScript 暴露了員工的電子郵件地址:
沒有人談論這個。沒有 VentureBeat 的頭條新聞關於 GitHub 在其 JS 捆綁包中發布電子郵件地址。沒有 Hacker News 的討論串關於 Anthropic 的 CDN 腳本中暴露的內部 URL。但這完全是同一類問題——生產環境的 JavaScript 暴露了從未打算公開的資訊。
您可以立即檢查自己的網站:afterpack.dev/security-scanner,或從終端機執行:
Claude Code 的外洩事件說明了一個比大多數報導暗示的更簡單的道理:
最小化從來都不是安全。它是一種尺寸優化。減慢人類讀者速度的變數重命名對 LLM 來說是微不足道的。AI 閱讀最小化程式碼就像你閱讀格式化程式碼一樣。
系統提示是新的商業機密。公司投入數月時間來設計塑造其產品的提示。Anthropic 的 Claude Code 提示——「# Doing tasks」、「# Executing actions with care」、「# Tone and style」部分——代表了嚴謹的提示工程工作。所有這些都以明文 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——揭示了尚未生產就緒的早期功能和實驗性端點。對攻擊者來說,這就是最少測試、最脆弱的攻擊面路線圖。對競爭對手來說,這就是你的整個功能管線。對你的用戶來說,這是一份他們從未被告知的控制項列表。
這適用於 Anthropic 以外的每一個 JavaScript 應用程式。每一個 React 前端、Electron 桌面應用程式、React Native 行動應用程式、Node.js CLI——都發布了 AI 現在可以閱讀、分析、重建和模仿的程式碼。帶有功能旗標的支付閘道。具有定價邏輯的 SaaS 產品。帶有硬編碼端點的驗證流程。
你剛剛閱讀的文章證明了最小化不是保護。但傳統的混淆也不是——至少現在不是了。
所有現有的 JavaScript 混淆器都是在 Opus 4.6 存在之前建立的。它們的技術——字串加密、控制流程扁平化、死程式碼注入——是循序漸進、可逆的轉換。每一步都有其反向操作。在數百萬個程式碼範例上訓練的 AI 模型可以識別並撤銷這些模式,通常在幾秒鐘內。
將設定調到最高,是的,你可以減慢分析速度——但代價是程式碼膨脹 10 倍和嚴重的效能下降。到那時,你就讓你的應用程式變得無法使用,以保護它不被閱讀。
這就是 AfterPack 所解決的差距。
AfterPack 採取了不同的方法。AfterPack 不是將可逆轉換層層疊加,而是使用非線性、不可逆的轉換——更接近雜湊函數的工作方式,而不是傳統混淆器的工作方式。輸出在功能上與輸入等效,但轉換破壞了語義意義,使其無法逆轉——即使是 AfterPack 自己也無法逆轉。沒有反向函數。沒有解鎖原始碼的密鑰。
核心思想是:不要只是讓程式碼更難閱讀。而是破壞攻擊者重建它所需資訊——就像雜湊函數破壞其輸入一樣。以偽隨機順序應用的 40 多種轉換意味著逆轉的複雜性不是線性的(先撤銷步驟 1,然後步驟 2)——而是組合式的。而且其中幾種轉換確實是資訊破壞性的:即使你識別出應用了什麼,原始碼也是無法恢復的。
而且,是的——你仍然可以除錯你自己的程式碼。AfterPack 會生成加密的原始碼對映檔案,將混淆後的輸出映射回你的原始碼。保護對攻擊者來說是單向的,對你來說則不是。
使用 Rust 編寫以獲得速度——足夠快,可以在每次建置、每次提交時運行,甚至在 Cloudflare Workers 的邊緣運行。並提供足夠慷慨的免費方案,讓你沒有理由不使用它。
目前的情況——一個價值超過 600 億美元的 AI 公司將其最敏感的客戶端程式碼僅以 bundler 最小化的方式發布——將不會持續下去。我正在建置 AfterPack,因為我認為保護應該是每個建置流程中的預設步驟,而不是事後補救。如果你好奇,可以在你自己的網站上試用掃描器——你可能會驚訝於暴露了什麼。
獲得唯一為 AI 時代而建的混淆器的早期存取權。
最後的建置步驟,讓你的邏輯免受掃描器、AI 和逆向工程的侵害。今天就停止發布原始碼。