ChatGPT 分享連結就能盜帳號:沙盒逃逸鏈全拆解

Parameter Labs 公開一條 ChatGPT 沙盒逃逸鏈:攻擊者只要把你加進一個公開分享的對話,你點開連結,對方就能用你的登入身分讀取私人對話。問題出在 MathLive 虛擬鍵盤的 postMessage 沒驗來源、innerHTML 直接吃 HTML、以及 CSP 允許的 YouTube oEmbed 端點。OpenAI 於 2026 年 10 月 26 日修補、評為 P1、發出 5,000 美元賞金。本文拆解完整攻擊鏈、官方時間線與四條防禦規則。

  • Dennis
  • 8 分鐘閱讀
ChatGPT 分享連結就能盜帳號:沙盒逃逸鏈全拆解

ChatGPT 的公開分享連結一度可以盜走別人的帳號:攻擊者建立一個含「圖表+HTML Preview」的對話、按下分享、把連結傳給你,你點開就能被讀走私人對話。 漏洞由 Parameter Labs 於 2026 年 10 月 18 日通報、10 月 26 日修補,OpenAI 評為 P1(最嚴重等級),賞金 5,000 美元。整條鏈的關鍵不是沙盒破了,而是主頁面上有一個願意聽任何人說話的監聽器。

這不是「模型被騙」那類 prompt injection 故事。這是傳統網頁安全的老問題,發生在一個每天有數億人開著的 AI 產品上——而且修補已經完成,公開的時間線與技術細節都值得記下來,因為同樣的錯誤正在被複製到每一個做「AI 生成網頁預覽」的產品裡。

事件一覽

項目內容
發現與通報2026 年 10 月 13~18 日驗證,10 月 18 日送交 OpenAI
修補完成2026 年 10 月 26 日(兩個前端版本都確認拒絕該訊息)
嚴重等級P1(OpenAI 最初 triage 為 P2,10 月 21 日複現後升級)
賞金總計 5,000 美元
影響範圍已登入 ChatGPT 網頁版、開到惡意分享連結的使用者
使用者需要做什麼已經修補,無需變更密碼;但「陌生分享連結」的風險意識仍適用
技術根因MathLive 的 postMessage 收件端未驗證來源+innerHTML 接受 HTML+srcdoc 建立無 sandbox 的 iframe

研究團隊在自家帳號之間完成 PoC,目前沒有公開證據顯示這條鏈曾被實際大規模利用——但攻擊門檻低到只要一個網址,這件事本身就足以讓所有做 artifact/預覽功能的團隊重新檢查程式碼。

完整時間線

Parameter Labs 公開的時間線,把「從發現到修好」的 13 天攤開來看,最有價值的是看到修補是分階段落地的:

日期(2026)事件
10/13在 ChatGPT 正式環境程式碼確認 MathLive「訊息→HTML」路徑可行
10/14透過正常 UI 複現整條鏈,把固定內容的 alert 升級成任意 JavaScript
10/16確認可跨帳號、跨 workspace 用公開分享投遞(受害者需點一次 Preview)
10/17確認從分享頁自動開啟 Preview,硬重新整理後仍可複現(約 4.5 秒後觸發)
10/18通報 OpenAI
10/19補上「讀取從未分享的私人對話」證據
10/21OpenAI 複現,嚴重度由 P2 升為 P1
10/22OpenAI 表示第一個前端已修、第二個還在更新
10/23CSP 調整先擋掉部分鏈路,但仍有前端待更新
10/26兩個前端都確認拒絕該訊息,問題關閉,賞金 5,000 美元

值得注意的是 10/22~10/23 那段:修補不是一次到位,而是先改 CSP、再改前端。對開發者來說這是個提醒——如果你的產品同時有多個前端(桌面版/網頁版/舊版入口),單一版本修好不代表整體修好。

攻擊鏈四步:兩個無害功能拼出一個漏洞

整條鏈最漂亮(也最可怕)的地方,是每一步單獨看都很合理。四個環節缺一不可:

步驟發生什麼事為什麼單獨看沒問題
① 對話裡有一張互動圖表圖表載入 MathLive,這個數學排版套件在主頁面安裝了虛擬鍵盤的 postMessage 監聽器圖表是正常功能,MathLive 是成熟套件
② HTML Preview 送出訊息Preview 在獨立網域的 sandbox iframe 裡,但 postMessage 本來就是跨框架合法通道沙盒確實有效:Preview 讀不到 parent.document
③ 監聽器把 HTML 塞進主頁面MathLive 的控制器 origin policy 是 none,任何來源都收;鍵盤 layout 允許原始 HTML,最後直接 innerHTML 進主頁套件作者大概認為「只有自己的鍵盤會送訊息」
④ CSP 被 YouTube 繞過注入的 srcdoc iframe 沒有 sandbox 屬性,因此繼承 chatgpt.com 身分;CSP 雖擋 inline script,卻允許 www.youtube.com,而 oEmbed 端點的 JSONP callback 會把 JavaScript 反射回來CSP 是「最後一道牆」的常見假設

研究員用的兩個訊息長這樣(節錄自 Parameter 原文):

top.postMessage({
  type: "mathlive#virtual-keyboard-message",
  action: "update-setting",
  layouts: [{ label: "Compatibility", layers: [{ id: "compatibility", markup }] }]
}, "*");

top.postMessage({
  type: "mathlive#virtual-keyboard-message",
  action: "show",
  animate: false
}, "*");

兩個訊息都用 "*" 當 targetOrigin,收件端也沒有回頭檢查 event.origin 與 event.source。這就是全部。沒有記憶體損壞、沒有 0-day 瀏覽器漏洞、沒有暴力破解。

為什麼 innerHTML 加上 srcdoc 就等於執行權

innerHTML 塞進去的 <script> 不會執行,這是很多人記得的常識——但 <iframe srcdoc="..."> 會重新解析一份新文件。當父頁面(chatgpt.com)建立這個 iframe 時,瀏覽器給它的是 https://chatgpt.com 的身分,於是裡面的程式碼可以存取父頁面、也能呼叫 ChatGPT 自己的 API。

研究員特別點出一件事:MathLive 有一個叫 createHTML 的輔助函式,看起來像消毒器,實際上是 Trusted Types 的 identity 包裝——把字串標記成「可信」然後原封不動送進去。Trusted Types 管的是「誰可以賦值到 HTML sink」,不是「內容安不安全」。

CSP 不是最後一道牆

繞 CSP 的手法也很典型:YouTube oEmbed 支援 JSONP 風格的 callback 參數,端點會先驗證 callback 是否合法,但在回傳錯誤訊息之前就把 callback 放進回應內容。研究員用 ;void 結尾吞掉後面接上的錯誤物件,就得到一段可執行的 JavaScript:

https://www.youtube.com/oembed?callback=globalThis.__marker=31337;void

回應開頭變成:

// API callback
globalThis.__marker=31337;void({ "error": { "code": 400, ... } });

因為 ChatGPT 的 CSP 已經允許 www.youtube.com,瀏覽器就把這段當 script 執行。整個 payload 並不短——最終 iframe 標記約 7,390 字元、內層 callback 5,533 字元——但瀏覽器不在乎長度。

拿到執行權之後,能做的事不是「彈個 alert」

驗證碼跑起來只是證明「在哪裡執行」。真正的影響是:程式碼跑在 chatgpt.com origin 上,等於擁有受害者已登入的完整權限。

研究員的做法是從頁面的 #client-bootstrap 取出 session access token 與 account ID,帶上兩個標頭直接打 ChatGPT 的內部 API:

Authorization: Bearer <victim token>
ChatGPT-Account-ID: <victim account>

然後兩個請求就够了:

GET /backend-api/conversations?limit=20&order=updated&offset=0
GET /backend-api/conversations/<id>?num_turns=2

第一個列出對話清單,第二個讀取指定對話內容——那個對話跟惡意分享完全無關,也從未分享給攻擊者。最後用一張圖片請求把資料帶出場(new Image().src = ...),這是繞過多數網路監控的老方法。

換句話說:這不是「看到畫面上有什麼」,而是「用你的身分呼叫 API」。同一個邊界內的任何操作理論上都能做,包含改設定、讀檔案、動帳號。

從「實驗室 PoC」到「一條人人都能轉傳的連結」

這段演進很值得看,因為它示範了「漏洞利用的包裝」如何決定真實風險:

版本投遞方式受害者需要做什麼問題
第一版研究員控制的 ChatGPT App 當發送者安裝/連接該 App太明顯,不是現實攻擊
第二版原生 HTML 附件點開附件匯出成公開分享時圖表不見了,MathLive 沒被載入,監聽器不存在
第三版一般公開對話:真圖表+助手產生的 HTML Preview點開分享連結(最好情況連 Preview 都不用點)可行,/share/<id> 完整保留整條鏈

第三版才是重點:攻擊者不需要你安裝任何東西、不需要你加入他的 workspace、不需要你貼程式碼、也不需要開開發者工具。你只要在已登入的狀態下點開一個看起來很正常的分享連結。

研究員也誠實記錄了鏈路的脆弱處:圖表與 Preview 是各自載入的,payload 有時會在 MathLive 準備好之前送出,最後的版本用「有限時間內重試」解決競態。這種細節反而是防禦方可以施力的地方——但前提是你知道有這個縫。

一般使用者該怎麼看這件事

漏洞已修補,以下不是「現在很危險」的恐慌清單,而是這類事件的長期習慣:

情境建議
收到陌生帳號傳來的 ChatGPT/AI 分享連結先看網域是否為官方網域,再決定要不要在已登入狀態點開
要開來源不明的分享頁用無痕視窗(未登入狀態)打開,或先登出再點
公司內部有人用 AI 工具做「HTML 預覽/小工具」要求資安團隊檢查預覽元件的 sandbox 與 CSP 設定
看到「AI 幫你做的網頁」可分享給他人理解那是我方伺服器在跑別人的程式碼,不是純文字

給開發者:四條可以直接拿去改 code 的規則

Parameter 的結論寫得很直白,這四條幾乎適用於每一個做「AI 生成 UI/artifact/預覽」的產品:

  1. postMessage 收件端要同時驗 event.origin 與 event.source,狀態變更類的訊息不能只驗其中一個,更不能設成 "*" 或 origin policy none。
  2. 跨視窗傳遞的設定值不應包含原始 HTML。要傳結構化資料(JSON),在接收端用安全的方式組版,而不是把字串丟進 innerHTML。
  3. 動態建立的文件要全程維持 sandbox,尤其當內容可以被不受信任的框架影響時。用 srcdoc 建立 iframe 卻不加 sandbox 屬性,等於把主站身分借給對方。
  4. CSP 是縱深防禦,不是唯一防線。只要攻擊者能注入 HTML 到主站,任何被允許的第三方 script 端點(CDN、oEmbed、JSONP 回呼)都可能是執行路徑。

還有一條比較少人提的:把「公開分享」當成不可信輸入。分享連結的設計初衷是方便,但它讓「別人寫的內容」變成「你網域下的內容」——這在威脅模型上就是一個必須重新評估的邊界。

5,000 美元賞金,貴還是便宜

Simon Willison 在 10 月 31 日的連結部落格評論這件事,用詞很直接:「對這麼嚴重的漏洞來說,5,000 美元有點便宜。」

這個判斷不是情緒。以「一條連結就能讀取付費訂閱者全部私人對話」的影響面來看,放在主流平台的 P1 獎金行情裡確實偏低;而更值得討論的是修補節奏——通報後 3 天複現、8 天修完,速度不慢,但中間有 4 天處於「一個前端修好、另一個還沒」的分裂狀態。對使用者來說,那 4 天就是風險窗口。

同時也要說公道話:這條鏈不是 OpenAI 獨有的設計錯誤,而是「互動式 AI 產出」這個新產品類別的通病——把模型生成的 HTML 當成可信內容來渲染、用第三方套件補功能、靠 CSP 當最後一道牆。這三件事同時做的產品,市面上遠不止一個。

站內延伸閱讀


本文為新聞解析,非投資或資安稽核建議。文中技術細節以 Parameter Labs 公開報告與 Simon Willison 的評論為準;漏洞已於 2026 年 10 月 26 日修補。

📬 訂閱 most.tw 電子報

每週精選 AI 工具教學與技術乾貨,直接送到你的信箱。免費、隨時可退訂。

訂閱即表示同意收到 most.tw 電子報,隨時可一鍵退訂。

💬 有問題想討論?加 LINE 聯絡我

歡迎透過 LINE 官方帳號直接留言,我會盡快回覆你的問題。

加入 LINE 好友