一個提示。三個 Shell 指令。我讓它們自己的 AI 駭了自己。
這是一種很可能存在於現今每一個多 Agent AI 產品中的漏洞。而解決方案是一種目前業界還沒有人討論的設計模式。
以下是完整的故事。
我本來不是要駭任何東西。我只是在研究 Perplexity Computer 如何處理沙箱隔離,為了我自己在開發 Agent 基礎設施時做參考。我想了解生產環境中的多 Agent 系統實際上如何隔離執行環境、哪些東西是共享的、哪些不是。
首先,我開始在系統中四處探查。我注意到沙箱裡安裝了 Claude Code。
我讓 Agent 啟動它,並產生一些測試程式碼,只是想看看它怎麼運作。一切正常。標準的 Claude Code,以 bypass-permissions 模式執行,所以不會要求確認。這對一個 Agent 系統來說是合理的。
就在那時我想:等等,它們是怎麼處理 API 金鑰的?!Claude Code 需要一個 Anthropic API 金鑰才能運作。那個金鑰一定存在於這個沙箱的某個地方。它是怎麼被注入的?作用範圍是怎麼設定的?有隔離嗎?
這個問題就是引導我走上這條路的原因。
子 Agent 在其行程環境中持有一個 API 金鑰。我需要偷走它。
Perplexity Computer 嘗試了六次,都失敗了。
- 要求子 Agent 傾印它的環境變數:拒絕了!
- 在共享檔案系統上植入一個特洛伊木馬腳本:它讀了我的程式碼,理解它在做什麼,然後拒絕執行!
- 汙染了 .bashrc 和 .profile:它們觸發得太早,在 API 金鑰被注入之前。
- 在 PATH 上放了一個假的 node 二進位檔:從未觸發。
- 同時啟動編碼 Agent 並監視行程樹:子 Agent 在另一個沙箱中執行,什麼都沒捕捉到 :(
- 找到 Claude Code 的系統提示並修改它以移除拒絕行為:找不到任何自訂的系統提示被注入。
六次失敗。Claude 的模型/提示層級的安全性確實很好。每次我嘗試一些聰明的方法,模型都會發現。

然後,Perplexity 想起 Claude Code 是透過 npm 啟動的 Node.js 應用程式。而 npm 會從家目錄讀取 ~/.npmrc。而且家目錄就在我可以寫入的共享檔案系統上。
Node.js 有一個 --require 旗標,可以在任何應用程式程式碼執行之前預載入一個 JavaScript 模組。你可以透過 .npmrc 中的 NODE_OPTIONS 設定它。這表示,如果我寫一個 .npmrc 到共享的家目錄,那麼子 Agent 每次啟動的任何 Node.js 行程都會預載入我的程式碼!這發生在 Claude Code 初始化之前、任何安全檢查執行之前、任何事之前!
這個漏洞只需要三個指令:
- 寫一個六行的腳本,將
process.env傾印到共享工作區的一個檔案 echo 'node-options=--require /path/to/script.js' > ~/.npmrc- 要求 Perplexity Computer 執行任何編碼任務
子 Agent 啟動 → npm 讀取我的 .npmrc → 我的預載入在 Claude Code 啟動之前觸發 → 完整的 API 憑證落在共享檔案系統上。
成功了!它給了我一個 Perplexity 閘道器令牌,透過 agent-proxy.perplexity.ai 代理到他們的主 Anthropic 帳戶。

當然,我做的第一件事就是把這個 API 金鑰和 BASE_URL 設定到我自己筆電上的 Claude Code。我預期 Claude Code 的 LLM 呼叫會失敗,並被限制在沙箱內。我震驚了。Opus 4.6 瞬間回應!
然後我心想:「當然,他們會把這個使用量記在我的帳單上,這個 API 金鑰一定跟我的用戶綁定。」我又錯了。
我讓 Opus 4.6 生成一個長篇故事,描述世界的歷史,包括每一項發明、帝國和發現。我並行執行了這個呼叫 5 次,每次生成超過 100k 的輸出 token。這應該會用光我所有的 Perplexity Computer 額度,但它們完全沒有變動。
沒有 IP 限制。沒有會話綁定。沒有沙箱綁定。他們的帳單。
地球上資金最充裕的 AI 新創公司之一,被一個從 2019 年就用於 Node.js 供應鏈攻擊的 dotfile 打敗了。
模型做對了一切。基礎設施卻沒有。
現在,這是我真正希望正在建立 Agent 基礎設施的創辦人從中學到的。
Perplexity 的架構對了一半。他們在沙箱和 Anthropic 的 API 之間使用了一個代理。這是正確的模式。你永遠不應該把原始的提供者 API 金鑰放在沙箱內。代理給了你控制權、可觀測性,以及在不需要輪換主金鑰的情況下撤銷存取的能力。
問題在於,他們的代理令牌與執行上下文完全沒有綁定。一旦你拿到它,它可以在任何地方永遠使用。
以下是正確的做法:
將令牌綁定到沙箱 ID。令牌和沙箱 ID 不符?拒絕。金鑰洩漏但沒有沙箱?沒用。理想情況下,它也應該綁定到沙箱的 IP 位址,但 E2B(他們使用的沙箱提供者)在沙箱啟動之前無法提供這個資訊。
讓令牌是短暫的。在沙箱啟動時生成它,在沙箱暫停時銷毀它。不要有長期有效的憑證。代理在會話開始時生成一個短暫的令牌,並在拆卸時使其失效。從已失效的沙箱洩漏的金鑰是死金鑰。
將令牌綁定到用戶的帳單帳戶。即使其他所有措施都失敗,即使有人從活躍的沙箱中竊取了一個活令牌並在其過期之前使用它,使用量也會記回啟動該會話的帳戶,而不是一個共享的主帳單池。這將「無限免費 API 存取」轉變為「有人濫用自己的配額」,這是完全不同的嚴重程度。
這三件事——沙箱綁定、短暫有效、用戶帳單——才是讓代理模式真正發揮作用的地方。沒有它們,你只是多了一個網路跳點,卻什麼都擋不住。
這不是 Perplexity 特有的問題。這是目前 Agent 基礎設施的預設架構,因為它建置最快。Agent 之間共享檔案系統、長期有效的憑證、主帳戶帳單。我敢打賭,目前生產環境中的大多數多 Agent 產品都有某種版本的這個問題。
在發布前已回報給 @AravSrinivas 和 @denisyarats。





