網頁改寫了代理的設定檔
2026年7月21日,Intezer 與 Kodem Security 揭露了 CVE-2026-10591:一個看似普通的文件頁面以一像素白字夾帶指令,當開發者請 AWS 的 Kiro 代理讀取它時,Kiro 用自己的檔案寫入工具,在毫無核准的情況下覆寫了啟動其 MCP 伺服器的設定檔,接著重新載入該檔並在主機上以開發者的權限執行了攻擊者的程式碼。AWS 加上了核准提示。真正留下的,是代理、它所讀的網頁與開發者的機器同屬一個信任區。Bromure Agentic Coding 在它們之間放上一層 hypervisor。
開發者請 Kiro 讀一個文件頁面。頁面裡有一句以一像素白字書寫的話,是寫給模型看 的,不是給眼睛看的。順著它,Kiro 改寫了決定自己啟動哪些程式的檔案,然後啟動了 一個。這一切都不需要點擊。
Kiro 是 AWS 的代理式 IDE:一個代你閱讀開放網路、抓取文件並替你接上工具的程式設計
代理。和 2026 年多數代理一樣,它說 Model Context Protocol,即 MCP:讓程式設計代理
呼叫外部工具並讀取其結果的插頭。Kiro 把它的 MCP 伺服器清單,以及啟動每一個所用的
確切指令,存在一個位於 ~/.kiro/settings/mcp.json 的樸素檔案裡。當這個檔案改變
時,Kiro 會重新載入它,並啟動它此刻所描述的一切。
最後這句話就是整個漏洞。這個檔案是個啟動器,而代理能寫入它。
2026年7月21日, Intezer 在與 Kodem Security 的研究中,展示了隨之而來的連鎖, The Hacker News 當天便報導了它。AWS 指派了 CVE-2026-10591, 評為 10 分中的 8.8。同一問題較早的片段,早已由 Johann Rehberger 與 Cymulate 指出。 Intezer 所加上的,是投遞。
一個你讀的頁面,而非你打開的檔案
指令並非來自某個儲存庫,或開發者選擇信任的設定。它們來自一個網頁。Intezer 把它們
以一像素白字、color:#fff;font-size:1px,種在一個其餘部分毫不起眼的 API 文件頁面
上。在瀏覽器裡,這段落什麼也不呈現:一條人類捲動時直接略過的空白細片。對於吞入
頁面文字而非其圖像的代理而言,它是一段清楚的指令。
這些指令要 Kiro 使用自己的檔案寫入工具 fsWrite,以攻擊者提供的項目覆寫
~/.kiro/settings/mcp.json。Kiro 沒問就照做了。它預設的 Autopilot 模式自行寫入該
檔,沒有對話框,也沒有「允許這次寫入嗎?」的提示。重新載入觸發,Kiro 啟動了新項目
裡的指令,攻擊者的程式碼便以開發者的權限在主機上執行:足以讀取憑證、複製原始碼、
植入持久化,或橫向移動到開發者機器所能觸及的一切。
AWS 加了提示。機器仍是獎品。
這修補是明智的。AWS 如今把 mcp.json、.vscode/tasks.json、.git 目錄,以及其他
對執行敏感的檔案標記為受保護路徑:寫入其中任一個都需要明確核准,Autopilot 與
Supervised 模式皆然。原先缺席的核准步驟,現在有了。若你使用 Kiro,請更新它。
這修補沒有改變的,是房間的形狀。AWS 在結語中也如此說:唯有當一個人被展示了那個 關鍵的步驟,且在模型被徹底說服而越線之後平台仍守住那條線,人在迴圈中才作為一種 控制發揮作用。這是兩項要求。提示滿足了第一項:它把寫入攤到眼前。它無法滿足第二 項,因為當程式碼執行時,它在開發者自己的機器上、以開發者自己的觸及範圍執行。你在 疲憊的午後一路點過去的核准,或是下一個聰明頁面學會措辭得讓它看來例行的核准,都把 你帶到同一個地方:攻擊者的程式碼,在你的金鑰、你的儲存庫與你的雲端工作階段所在之 處執行。
這裡反覆出現的形狀 — 代理讀過的頁面、它能寫的設定、它能觸發的啟動 — 並非 Kiro 獨有。它就是一個閱讀開放網路、並在滿是機密的機器上編輯檔案的代理的樣子。持久的 問題是:代理在哪裡執行,以及當提示失效時它周圍有什麼。
Bromure 執行相同步驟之處
Bromure Agentic Coding 不試圖讓代理不信任頁面、拒絕寫入或攔下點擊。它改變整個序列 所執行的那台機器。每個設定檔的代理,都在 Apple Silicon 上一個用完即棄的 Linux VM 裡執行,與 macOS 隔著一層 hypervisor。在那裡執行 CVE-2026-10591 完全相同的連鎖, 每一步仍會觸發,而每一步都落在不同的地方。
頁面被讀取。注入得逞。Kiro 的替身改寫 mcp.json,重新載入觸發,攻擊者的指令「以
開發者的權限」啟動。只是在 VM 裡,開發者是一個用完即棄的箱子中的 ubuntu 使用者,
而那箱子裡沒有任何值得跑這一趟的東西。程式碼去尋找那些讓攻擊划算的憑證 —
Anthropic 金鑰、AWS 金鑰、GitHub 權杖 — 找到的卻是誘餌。在 Bromure 中,真正的機密
從不進入 VM;主機上的一個憑證仲介注入像
brm_… 這樣的佔位符、一份合成的 kubeconfig,以及一把用完即棄的 SSH 金鑰,只在
網路邊界、對你已核准之目的地的請求上,才換入真正的值。原始碼竊取只觸及你選擇掛載
的資料夾。「橫向移動進內部系統」則觸及每個設定檔各自的 VM 防火牆。
接著是外送的那一半。竊取一個誘餌,唯有你能把它送到某處才划算;而橫向移動意味著 抵達第二台主機。兩者都是網路動作,在 Bromure 中兩者都穿過主機代理,在那裡一個請求 真正的目的地會在外送途中被把關,而一個動作的破壞性形態 — 對設定檔所代管的雲端與 git API 發出的 delete、drop 或 terminate — 會遇上一道能拒絕它的護欄,無論代理被 說動去做什麼。被啟動的程式碼所嘗試的一切,都會在工作階段軌跡裡留下一行記錄。
而在這一切之前還坐著一層,理由正好貼合這場攻擊。Bromure 會為代理所讀的不受信任
內容 — 一個抓取的頁面或一則工具回應 — 在模型據以行動之前,用一個裝置端的
注入偵測器評分。一像素文字之所以有
效,是因為人讀的是渲染後的頁面。分類器不然;它讀的是模型所讀的同一道原始串流,在
那裡 color:#fff;font-size:1px 什麼也藏不住。那個讓段落對眼睛隱形的把戲,對讀取
位元組的評分器毫無差別。它攔下其中大部分,而夠新奇的偽裝仍可能溜過單一偵測器,因
此它坐在用完即棄的箱子之前,而非取代它。
如今網路就是那不受信任的輸入
多年來,給程式設計代理的建議是:小心你信任哪些儲存庫。Kiro 把這課往前推:危險的 輸入是一個文件頁面,代理一天要讀上百次的那種,而武器是一個瀏覽器自 1990 年代就一 直尊重的 CSS 屬性。隨著開發流程越來越多經由閱讀開放網路的代理,每個頁面都是不受 信任的輸入,而讀得再仔細也修不好這件事。
AWS 加上的提示是正確的修補,也應該推出。但一個仰賴某人在每個頁面上、永遠地抓到那 唯一要緊的寫入的控制,是一個長期成績很差的控制。Bromure Agentic Coding 不要求代理 對網路小心。它假定頁面得逞、設定被改寫、程式碼執行,並確保當這一切發生時,是發生 在一個沒有東西可拿、也沒有回家路的箱子裡。這就是一個你能用言語繞過的提示,與一條 畫在低一層、言語在那裡失效的線,兩者之間的差別。安裝它,給你的 代理一台不是你輸得起的機器。