一張生成的抽象插圖,背景為深藍色:左側的瀏覽器視窗外框將一條由淺色、類似字符的形狀組成的帶狀圖形,穿過一個狹窄的發光接口,送入右側的終端機面板。第二條顏色較深的帶狀圖形從下方接入同一個接口,其字符抵達終端機時,與第一條的字符無法區分。圖中沒有出現文字、人物或組織標誌。OrcaRouter 標誌置於右下角的白色頁尾條中。
AI Safety Incidents

騰訊 BrowserSkill 只檢查擴充功能 ID 看起來是否真實——任何擴充功能都能向代理程式餵入偽造頁面

作者

Rowan Sterling

發佈日期

最新模型 · 20查看全部模型 →
基準測試:Artificial Analysis · 每日更新
返回全部文章

在2026年9月17日,一位 GitHub 使用者(發文者:carfeii)開立了 issue #273,針對 Tencent 的開源BrowserSkill 專案,提出一項範圍狹窄的主張:將瀏覽器擴充功能連接到 AI 代理程式的本機常駐程式並未檢查 哪一個 擴充功能連線,只確認該連線看起來像個擴充功能。三天後,於 9月20日,VulnCheck 將該發現發布為 CVE-2026-94111,描述一個「接受任何在 a-p 範圍內有 32 個字元的 chrome-extension origin」的常駐程式,並將其分類為 CWE-346(來源驗證錯誤),並歸功於 George Chen。該公告將其評分為 CVSS 4.0 6.9,中等,完整性影響評為高,機密性與可用性則評為低。紀錄中沒有任何跡象顯示該漏洞曾被利用:該檔案庫未記錄任何利用行為,並將該條目的信心等級評為 A,且 real_harm 為 false。這是AI 事件檔案中的一筆紀錄,其中每筆條目都帶有自己的來源、嚴重程度、信心等級與爭議標記。

一個從未檢查身分的格式檢查

這份紀錄核心的程式碼很小。在 crates/bsk-cli/src/daemon/ws.rs 中,函式 origin_allowed() 會取得 WebSocket 握手的 Origin 標頭,移除字串 chrome-extension://,若剩下內容正好是 32 個字元長,且每個字元都介於 a 與 p 之間,就回傳 true。這就是完整的測試。它會在 HTTP 升級回呼中執行一次,失敗時會回傳 403,訊息為「Origin not in chrome-extension allow-list」——不過就發布的版本而言,根本沒有可供列入的清單。

這個模式並非任意。Chrome 的 Manifest V3 擴充功能 ID 是 32 個字元,且恰好由那十六個字母組成,因此這項檢查能正確辨識出真實擴充功能來源的形狀。缺陷在於每個擴充功能都有那個形狀。這項檢查只問呼叫端看起來是否像瀏覽器擴充功能,卻從不問它是否是這個專案的瀏覽器擴充功能;而它原本應該拿來比對的識別碼早已公開:該專案的 README 連結到 Chrome Web Store 商品頁面,其 ID 是 hhcmgoofomhgciiibhipgmgkgnoenaoi,旁邊還有 Edge Add-ons ID。這兩個字串都沒有出現在這道檢查關卡中的任何地方。

此常駐程式會監聽固定的本機通訊埠,52800,該埠在 CLI 中宣告為 DEFAULT_WS_PORT,並在本機連線路徑中固定使用、不作變更。此通訊埠已有文件記載、維持不變,且使用者瀏覽器設定檔中任何已在執行的項目都能連上。位置正是此公告的攻擊向量以 AV:L 開頭的原因——攻擊者需要在該機器上取得立足點,而 PR:L 記錄低權限的立足點就足夠。安裝在同一設定檔中的擴充功能正是那類立足點。

這個席次值多少,以及其中有多少已經確立

該安全公告的影響描述相當寬泛:攻擊者若能將惡意擴充功能註冊為瀏覽器用戶端,就能「攔截並操控回傳給 AI 代理的頁面內容、DOM 與螢幕擷取畫面」。這正是 CVE、GitHub 安全公告記錄 GHSA-x6f2-qp26-2xrh 與存檔所載的描述,也說明了 CVSS 完整性評級為高的原因。這同時是由指派 CVE 的一方所撰寫的摘要,並非對已演示攻擊的報告。

同一週,在 issue 討論串本身,出現了更審慎的說明。9 月 20 日,一位以bb6894名義留言的評論者表示,他重新對照 main 分支的 commit fa953dc6(9 月 18 日)檢查程式碼,並追查外部用戶端在握手後實際能觸及什麼。該留言指出,大多數傳入的工具方法會對 WebSocket 對等端傳回 UnknownMethod;稽核請求的範圍僅限於用戶端自己的紀錄;而 window_closed、user_interrupt 與 update_interaction 等跨工作階段動作,則會受到防護,避免涉及另一個瀏覽器所擁有的工作階段。能通過這層過濾的情況範圍更窄,而且對代理而言,可能比攔截更糟:外部擴充功能可以用攻擊者選定的 instance_id 佔用一個瀏覽器插槽;若它是唯一註冊的瀏覽器——例如冷啟動或常駐程式重新啟動——它會收到代理的工具請求,並以捏造的頁面內容、DOM 或螢幕擷取畫面來回應。該評論者稱此為「對代理的結果偽造」以及「通往代理感知的通道」。第二個影響是阻斷服務:若同時有真實瀏覽器在線上,且沒有選擇器,工作階段啟動可能會因 MultipleBrowsersOnline 而失敗。

這兩種說法都未曾在公開場合得到演示。舉報者將概念驗證描述為「可應要求提供」;沒有人發表過任何概念驗證,也沒有記錄到任何利用行為。因此,這兩種說法之間的差異,是對同一份原始碼檔案的兩種解讀之間的差異,而不是理論與可用漏洞利用之間的差異——而該報導是兩者都報導,而非從中選擇。可以無條件地說的是,握手之後從來沒有第二次身分檢查,因此無論閘門放行了什麼,在連線存續期間都一直保持放行狀態。

程式碼早就知道了

這份紀錄中最令人不安的文件不是該公告,而是該公告所指的已標記發行版中,直接位於該函式上方的註解。它將這個缺口標為 TODO(M10/M12),指出它打算建立的允許清單——一個 DaemonConfig::allowed_extension_ids 集合,由設定檔或配對流程填入——接著說明延後的理由:「目前是可接受的縱深防禦缺口,因為配對是透過彈出視窗進行,但同一台機器上的側載擴充功能目前仍能通過這道關卡。」

平實讀來,維護者知道這道關卡放行了哪個呼叫者,也把他們知情這件事寫了下來,然後就發布了。這不會讓暴露範圍比公告所述更大;它只是讓這件事不那麼令人意外,並把問題從「這怎麼通過審查」轉移到「原本要有什麼,才會讓延後修復變得迫切」。緩解性的設計假設確實存在,也有文件記載:本機連線是選擇性啟用。根據 README,使用者要安裝擴充功能、開啟其彈出式視窗,並啟用本機連線,而且守護程式必須正在執行,這一切才可能觸及。已安裝擴充功能但關閉開關,或沒有 bsk 守護程式在執行的設定檔,並不是可被連線的目標。

五週後,那扇門依然未變。

An HTML timeline card titled 'From a filed issue to an unmerged patch', subtitled 'Nine dated entries in the BrowserSkill daemon origin-check record', listing: 16 September 2026 BrowserSkill extension 0.3.0 tagged; 17 September the bsk CLI 0.3.0 release, and issue #273 filed the same day at 15:14 UTC; 20 September CVE-2026-94111 published by VulnCheck and listed by NVD and GitHub, with a narrower impact analysis posted in the thread; 21 September CISA's SSVC assessment records exploitation none and automatable no; 23 September CLI 0.3.1 released with the same origin check; 28 September pull request #363 opened from a fork to pin the store extension IDs; 30 September CLI 0.3.2, same check; 15 October CLI 0.3.3, same check; 27 October issue still open and the patch still unmerged. A footer cites the GitHub issue, the VulnCheck advisory, NVD and the project's release tags, with the OrcaRouter logo in a white strip at the bottom right.

該記錄的受影響範圍為「至 0.3.0(含)」,而這正是 CNA 所指派的範圍。但在儲存庫中,事情並不止於此。CLI 的 0.3.0 版本於 9 月 17 日 02:22 UTC 標記;該問題於同日 15:14 UTC 提出,大約十三小時後。此後又發布了三個 CLI 版本——0.3.1 於 9 月 23 日0.3.2 於 9 月 30 日0.3.3 於 10 月 15 日——而在這些標籤上,origin_allowed() 函式都是上述相同的檢查,其上方仍保留著 TODO。截至 10 月 27 日,主分支也同樣如此。

已有修正方案,但僅止於提案。在9 月 28 日,一名貢獻者(帳號為 dangzitou)從個人 fork 提出了 pull request #363,標題為「fix(daemon):將 WS 來源閘門固定至 BrowserSkill 自身的擴充功能 ID」。它以與兩個商店 ID 的比對取代形狀測試,並新增 BSK_ALLOWED_EXTENSION_IDS 作為側載與開發建置的明確准入路徑,這些建置的未封裝 ID 是從安裝路徑衍生而來。該 pull request 的內文聲稱,它同時封堵了偽造路徑與 MultipleBrowsersOnline 阻斷服務攻擊。截至 10 月 27 日,它仍處於開啟且未合併狀態,而該問題也仍保持開啟,且未附有任何廠商聲明。

實際後果是,沒有包含此修復的版本可供升級。任何建議「升級超過 0.3.0」的人,都是在建議一個尚不存在的步驟:後續版本只是較晚發布,並未修復。該記錄的範圍應理解為 CNA 於 9 月 20 日評估的範圍,而不是表示 0.3.1 及之後版本已無問題。

什麼是已經確立的,什麼不是

• 已確認:發佈於標籤 cli-v0.3.0 的原始碼中包含一道來源閘門,會接受任何由 a 至 p 組成、長度為 32 個字元的 chrome-extension 來源。檢舉人、CNA 與檔案本身三方說法一致,且該程式碼是公開的。

• 建立: 閘門僅在 WebSocket 升級時執行一次,之後不再進行身分檢查,且固定在本機連接埠 52800 上。

• 已確認:該專案自身的原始碼註解承認,側載的擴充功能會通過,並將允許清單延後處理。

• 已確立: CVSS 4.0 6.9 與 CVSS 3.1 6.6 皆為 VulnCheck 的評分,並由 NVD 記錄為次要。NVD 對該條目的自身狀態為 Deferred,意即其已發布 CNA 的資料,但未加入由 NVD 撰寫的分析。

• 已確立: CISA 的 SSVC 評估(日期為 9 月 21 日)記錄利用狀態為無、可自動化為否,技術影響為部分。截至 10 月 26 日,FIRST 的 EPSS 將未來三十天內遭利用的機率定為 0.00135,位於第 2.9 百分位。

• 尚未證實:任何實際使用情形。沒有漏洞利用、沒有公開的概念驗證、沒有受影響的安裝數量。該專案的儲存庫指標並非安裝數量的統計,且無人公佈過這樣的數量。

• 尚未確定:哪一種影響說法成立。CNA 的「攔截並操縱」與該討論串的「結果偽造加上阻斷服務」描述了不同的上限,而兩者都尚未在程式碼閱讀之外獲得證實。

• 尚未確立:該缺陷止於 0.3.0。此版本字串是 CNA 的評估;其後三個發行版中的程式碼並未改變,且沒有廠商聲明能排除這些版本。

• 矛盾且未解決:某個聚合器 DevGuard 針對此 CVE 顯示「已偵測到利用嘗試」的訊號,卻未指明來源、IOC 或遙測資料提供者。這與 CISA 記載的「未遭利用」評估相牴觸,也與沒有任何公開報告的情況不符;該檔案庫同樣未記錄任何利用情形。應將該聚合器的標記視為未經證實,而非第二個資料點。

An HTML card titled 'Established, and not', split into two columns. The left column, headed 'Established', lists: an origin gate that accepts any 32-character a-p chrome-extension origin, in the released cli-v0.3.0 source; checked once at the WebSocket upgrade on local port 52800; the project's own comment conceded sideloaded extensions pass; CVSS 4.0 6.9 and 3.1 6.6 are VulnCheck's scores, NVD status Deferred; CISA SSVC records exploitation none and automatable no; EPSS 0.00135 as of 26 October. The right column, headed 'Not established', lists: any real-world use or published proof of concept; which impact account holds, interception or result forgery; that the flaw stops at 0.3.0, since 0.3.1 to 0.3.3 carry the same check; an installation count; an unsourced aggregator claim of exploitation attempts. A footer cites VulnCheck, NVD, CISA, FIRST and the GitHub issue, with the OrcaRouter logo in a white strip at the bottom right.

為什麼傳輸層是值得關注的目標

大多數提示注入防範指引都劃定同一條界線:把擷取到的頁面文字視為不可信,而把傳送這些文字的機制視為可信。一般假定讀取網頁的工具就是在讀取該頁面;問題只在於頁面說了什麼。這份紀錄把這一點反轉過來。代理程式所收到作為頁面內容的 DOM 與螢幕截圖,其實是本機通訊端另一端的用戶端選擇要傳送什麼就是什麼;而那道通訊端上唯一的關卡,問的是一個每個候選者都能正確回答的問題。若用戶端是外來的,「驗證頁面說了什麼」就再無可供比對驗證的依據。

這也是為什麼嚴重性會落在目前這個等級,而不是更高。這項攻擊屬於本機攻擊,它假定設定檔中已安裝某個擴充功能或其他本機程式碼,並且要求常駐程式正在執行且已啟用本機連線。這些條件對該工具的目標使用者而言很平常,對其他人則不尋常。該存檔的中等嚴重性及其記錄的無害結果與這種形態一致:信任確實被擴大到設計原本應該把關的那個確切邊界,但沒有證據顯示有人越過它。

以下這些範圍狹窄的實務建議,並非任何人已公開的緩解措施,而只是程式碼所留下的界線。由於准入是在已發佈連接埠上的握手階段一次性決定,可觸及的範圍便取決於執行該 daemon 的設定檔中安裝了哪些擴充功能,以及當時該 daemon 與該擴充功能的本機連線是否已啟用。在擴充功能 ID 允許清單推出之前,這兩項事實就是控制的全部。

A generated abstract illustration on a dark navy field: two identical hexagonal tokens of the same size and colour approach a narrow blue aperture from opposite sides; both pass through, and beyond it their outputs merge into a single stream of pale glyph shapes entering a terminal panel. A faint dotted outline of a browser window sits above. No text, people or organisation logos appear. The OrcaRouter logo is set in the white footer strip at the bottom right.

CVE-2026-94111 會以兩種方式之一演變。要麼該 pull request 被合併,而這筆記錄會成為一則簡短條目,說明一個花了些時間才處理的已知缺口;要麼一年後同樣的形狀檢查仍留在程式樹中,而這筆記錄會被引用為其所屬類別的早期範例:不是帶有惡意指令的頁面,而是決定代理程式正在讀取哪個頁面的管道。