那個 token 從隔壁的行程漏了出來
研究人員從相鄰的一個 Cloudflare Worker 裡以每秒 12 位元拉出了一枚 JWT,沒有逃出沙箱,也沒有動用任何記憶體安全漏洞。isolate 的邊界始終沒破。祕密還是越過去了,走的是底下的硬體。如今雲端平台正把同一道邊界拿來執行 AI 代理程式寫出來的程式碼。Bromure Agentic Coding 把線畫得更低一層,並且乾脆不把你的憑證放進那個盒子裡。
某個租戶的 JavaScript 向 CPU 問了幾百萬個形狀經過設計的問題,然後從答案裡讀出了另 一個租戶的驗證 token。它始終待在平台為它畫的邊界之內,跑的是普通的 JavaScript,而 那道邊界從頭到尾都在盡責。
8 月 17 日,一組研究人員發表了 Remote-Timer-as-a-Service,19 日 Cloudflare 也貼出 自己對這項研究的說明。 他們從正式環境中一個同處一地的 Cloudflare Worker 裡,以最高每秒 12 位元、99.16% 的準 確率,拉出了一枚 JSON Web Token,也就是服務用來確認你身分的那串簽章字串。針對同一個 平台,先前公開的成果來自 2021 年,速度是每分鐘 2 位元。到了 360 倍的速率,你就跨過了 奇聞與被竊憑證之間的那條線。
Cloudflare 已經修好了,三年來沒有發現任何人用過的跡象,也表示沒有客戶資料遭到存取。 往下讀,看看這場攻擊自始至終都不必做的事。
沒有任何東西非壞不可
Cloudflare Workers 用很少的硬體跑很多租戶,做法是省掉平常把他們隔開的那樣東西。用 Cloudflare 自己的話說,Workers「在同一個作業系統行程之內,以彼此分離的 V8 isolate 執 行多個租戶的程式碼」。isolate 是 JavaScript 層級的容器:自己的堆積、自己的全域、沒有 共享記憶體、沒有執行緒。它在幾毫秒內啟動,而那正是重點所在,因為行程隔離會讓你在每 一個請求上都付出冷啟動的代價。
攻擊者需要的是跑在某個 isolate 裡的程式碼。把受害者弄進同一個行程才是漂亮的部分:攻
擊者的 Worker 去呼叫受害者。就像研究人員寫的,從攻擊者的腳本用
fetch("https://victim.example") 呼叫受害者,「多數情況下會讓排程器在完全相同的行程
裡啟動一個受害者 worker 的實例」。你不必等待同處一地,你把它召喚出來。
從這裡開始就是 Spectre 了。誤導分支預測器,讓 CPU 推測執行一次它本來絕不該做的讀取,
再量測快取,看它讀到了什麼。Cloudflare 早已花了數年把這件事變難:沒有
SharedArrayBuffer、沒有執行緒、計時器被凍結並粗化,讓你量不到小到像一次快取命中那
樣的東西,還有 Dynamic Process Isolation(DyPrIs),它盯著硬體效能計數器,把任何聞起
來像 Spectre 的東西挪進獨立行程。
研究人員把這些一個個繞了過去。
時鐘來自外面。連到 Durable Object,或連到網際網路上一台普通時間戳伺服器的 WebSocket, 就能在一個拒絕給你時鐘的平台裡拿到次毫秒等級的解析度。接著他們沒有去提高解析度,而 是把訊號放大:L1 快取的 tree-PLRU 置換策略沿著二元樹指標走,所以一次快取事件可以被變 成一長串命中,或一長串失誤。他們寫道:「單一快取事件的時序可以被任意放大。」只要你把 要計時的東西弄得夠大,模糊的時鐘就夠用了。
DyPrIs 錯過了兩次。它是在呼叫「結束之後」才隔離腳本,而靠 keep-alive 訊息維持存活的 Durable Object 可以跑上好幾個小時、最長到一整天,於是這個 exploit 在一次永不結束的呼 叫之內就完成了。它還會用 iTLB 存取次數把分支預測失誤正規化,而用 Cloudflare 的話說, 「我們的遠端計時器就是一個大型 I/O 迴圈,那些 WebSocket 流量會把 iTLB 活動撐大」。研 究人員把自己的分母養大,直到警報顯示一切正常。
剩下的都是水電工程:一個推測型別混淆的 gadget 用來洩漏 isolate 的根位址,對 typed array 的 backing store 做 64 位元指標混淆,把它變成任意讀取,然後是受害者的 JWT,一次 一個位元。
修補比發現說得更多
Cloudflare 推出了三項緩解措施。請把它們合起來讀。
他們整合了 V8 Sandbox,把原始的 64 位元指標從 JavaScript 堆積區域裡移走,殺掉了 typed array 那個 gadget。他們教會 DyPrIs 把長壽的 Durable Object 與 I/O 密集的工 作負載當成第一級的安全案例,而不是雜訊。他們還部署了 Memory Protection Keys,在共 用行程之內,把每個租戶的堆積放到一道由硬體強制的存取邊界後面。
三項全都往 JavaScript 底下伸手,去找比 JavaScript 語意更硬的東西,而第三項直接落在 CPU 本身。Cloudflare 坦白表示 V8 Sandbox「並不是完整的 Spectre 緩解措施」。用加上一道 硬體層級邊界的方式來修補語言層級邊界的工程師,已經告訴你他們認為真正的線在哪裡。
一個談代理程式編碼的部落格,寫起了 CDN
isolate 已經離開 CDN 了。3 月,Cloudflare 以
Sandboxing AI agents, 100x faster
為題推出 Dynamic Workers,一種在執行期用一秒前還不存在的程式碼啟動 Worker 的做法。如
果你跑過會自己寫、自己執行腳本的代理程式,你懂那個動機:「如果一個代理程式(或一個
MCP 伺服器)要執行 AI 即時產生的程式碼來完成任務,那些程式碼總得跑在某個地方」,而且
「你不能直接在自己的應用程式裡對 AI 產生的程式碼下 eval()」。
Cloudflare 在同一篇文章裡點名了那個機制:「Dynamic Workers 使用的,正是整個 Cloudflare Workers 平台自八年前推出以來一直賴以建立的底層沙箱機制:isolate。」理由是速度。一個 isolate 用幾 MB 記憶體在幾毫秒內啟動,大約比容器快 100 倍、記憶體效率高 10 到 100 倍, 於是「每個請求一個全新沙箱」變得負擔得起,而不必去用一個你反覆重用、每一輪都更弱一點 的溫池。
Cloudflare 對代價說得很坦率。他們自己的 beta 文章用八個字講完:「V8 的安全漏洞比 hypervisor 的漏洞更常見。」 那是在有人漏出 token 的好幾個月之前寫下的。
所以這裡的故事是一樁交易,由做這筆交易的人自己寫下來,如今又被研究人員標上了每秒 12 位元的價格。問題落到了其他所有人身上。當被放進沙箱的程式碼是模型寫的,被某個套件或某 個網頁講的話塑形過,然後被留在一枚 bearer token 旁邊跑著,那是你想要的交易嗎?
Bromure 把線畫在 hypervisor
Bromure Agentic Coding 不會把你的代理程式放進一個語言層級的容器,跟別人的程式碼擠在一 起。每個工作區都是一台跑在 Apple Virtualization.framework 上的 Linux 虛擬機,只支援 Apple Silicon:自己的核心、自己的客體記憶體、自己從唯讀基底映像複製出來的磁碟。沒有共 用行程,就沒有可以召喚的同居租戶;你的代理程式所在的那道邊界是 hypervisor,也就是 Cloudflare 自己那個比較裡漏洞比較少的那一邊。
那是架構層面。真正會讓這場攻擊變得毫無意義的東西更窄,而且還要再往裡走一步。
token 從來就不在盒子裡
研究人員帶走的,是一枚躺在受害者位址空間裡的 JWT,也就是一個執行中的服務放置自己所用 憑證的地方。他們沒有拿到 shell,也沒有拿到 root。
Bromure 的工作區不會把憑證放在那裡。
一個設定檔裡的每一個祕密都留在你的 Mac 上。這涵蓋 ANTHROPIC_API_KEY、GitHub 個人存
取權杖、AWS 存取金鑰、kubeconfig 的 bearer token、容器登錄檔的 Basic-auth blob,以及
Linear 金鑰。Bromure 注入虛擬機的是假的:一個 brm_… 佔位字串、一張用完即丟的用戶端憑
證、一段衍生出來的 Basic 字串。代理程式讀它,SDK 讀它,git、kubectl 和 doctl 也
讀它,工作照樣跑得通,因為主機上的 MITM proxy 會在外送請求上換回真正的值。AWS 那邊還
多鎖了一圈:主機會用真正的材料重新簽署 SigV4 請求,所以任何繞過 proxy 的東西從 Amazon
拿回來的是 InvalidSignatureException,而不是一次成功的呼叫。
於是,一個在那台虛擬機裡握有完美任意讀取能力的攻擊者,也就是研究人員花一整篇論文才建 出來的那個 primitive,讀到的是誘餌。位元組確實在那裡,能被解析,看起來像一把金鑰,卻 在機器外買不到任何東西。不論隔離邊界是否完美無瑕,你都能得到這個結果,因為工作區裡根 本沒有值得偷的東西。
每秒十二位元,還是得有地方可去
側通道只是外洩的一半。另一半是一條往外的路,而每秒 12 位元代表這條路得開著一陣子。一 枚 400 字元的 token,意味著要往攻擊者控制的目的地送上好幾分鐘的流量。
一個 Bromure 設定檔帶著自己的 egress 規則,寫成一小段 pf 風格的政策,並以表格的形式編
輯。強制執行的是你的 Mac,發生在虛擬交換器與 proxy 裡,客體內部的任何東西都沒有發言
權:被拒絕的連線會收到 reset,而這個決定會帶著主機、IP、連接埠與判定,變成
Window → Security Timeline 裡的一列 egress.firewall。跑在工作區裡的程式碼,站在
它想改的那些規則的錯誤那一側。
你也可以在每一次動用真憑證時按住它。對每個祕密打開 Require approval to use:模型的 API 金鑰、SSH 簽章、GitHub 與 GitLab 與 Bitbucket 的權杖、每個 kubeconfig 情境、 DigitalOcean、每一次 AWS SigV4 簽章、每個容器登錄檔,以及你自己加上的任何手動權杖規 則。替換會就地停下,等一個 macOS 上的對話框,你可以授權五分鐘、一小時,或整個工作階 段。客體永遠沒有機會回答那個問題。
交易本身才是故事
isolate 是很好的工程,而 Cloudflare 的處理方式正是你會希望看到的:協同揭露、三項實在的 緩解措施、對 V8 Sandbox 涵蓋什麼與不涵蓋什麼絕不打太極。每秒數百萬個請求不跑在容器上, 是有原因的。
冷啟動是在 CDN 上贏得這場爭論的東西,但你的編碼代理程式並不是在四毫秒內回答一個 HTTP 請求。它會跑一個小時,裝上沒有人稽核過的套件,執行模型寫的測試套件,讀那些很想跟它說上 幾句話的網頁。不論是什麼在跑這個工作負載,它在整段期間都握著你的權杖,而關於它所執行的 程式碼,你唯一知道的事情就是那不是你寫的。
對這樣的工作來說,幾百毫秒的虛擬機開機時間不是值得省下的成本。Cloudflare 已經公布了匯 率:V8 的漏洞比 hypervisor 的漏洞更常見。Bromure 站到這筆交易的另一邊,然後順手把權杖 也帶出了房間。
資料來源:Schwarzl, Xiao, Pedersen, Ainsworth, Topham,「Remote-Timer-as-a-Service: Efficient Microarchitectural Leakage in the Cloud with Remote Timers」(arXiv:2608.17043,2026 年 8 月 17 日) · Cloudflare,「A revisit of remote Spectre attacks on Cloudflare Workers」(2026 年 8 月 19 日) · Cloudflare,「Sandboxing AI agents, 100x faster」(2026 年 3 月 24 日) · The Hacker News,「Cloudflare Workers Spectre Attack Leaks JWT From Co-Located Worker at 12 Bits/Second」(2026 年 8 月 19 日)