11月1日、Simon Willisonが「How We Took Over ChatGPT Accounts」と題した記事を公開した。これはParameter Labsが発表したChatGPTの脆弱性レポートを取り上げたものであり、ChatGPTのHTMLプレビュー機能(Artifacts実装)に存在したアカウント乗っ取り可能な脆弱性と、その攻撃チェーンの詳細が紹介されている。
攻撃の起点:サンドボックス化されたiframe
ChatGPTには、インタラクティブなHTMLアプリをサンドボックス化されたiframe内で表示する機能がある。OpenAIはこれをかつて「Canvas」と呼んでいたが、現在はHTMLプレビュー(HTML previews)という名称で提供されている。いわゆる「Artifacts パターン」の実装だ。
この機能の安全性の前提は、iframe内のコードが厳格にサンドボックス化されており、OpenAIのAPIや親ページのデータに触れられないことにある。Parameter Labsが発見したのは、その前提を崩す多段階の攻撃チェーンだ。
攻撃チェーンの全貌
攻撃は単純な穴を突いたものではなく、複数の脆弱性を連鎖させた複合的なエクスプロイトだった。
ステップ1:MathLiveの仮想キーボードを悪用
OpenAIはグラフ描画のサポートのため、MathLiveというJavaScriptライブラリを使用している。このライブラリには仮想キーボード機能が含まれており、postMessage() を介してサンドボックス化されたiframeから親ページの仮想キーボードを呼び出せる設計になっていた。
問題はそのメッセージ受信側のコードにあった。**innerHTMLを使ってDOMを書き換える実装**だったため、postMessage()を送れる主体であれば誰でも、親ページに任意のHTMLを挿入できる状態だった。そして、HTMLプレビュー用のiframeがこのメッセージを送ることを防ぐ仕組みは存在しなかった。
ステップ2:サンドボックスなしのiframeを注入
innerHTML はscript要素を直接実行しないため、JavaScriptの即時実行はできない。しかしここで攻撃者は別の手を使う。サンドボックス属性のない新たなiframeを親ページに注入するという方法だ。これにより、制約のないコンテキストでのHTMLレンダリングへの足がかりを得られる。
ステップ3:YouTubeのoEmbedエンドポイントでCSPを回避
OpenAIはContent Security Policy(CSP)でインラインスクリプトを完全にブロックし、スクリプト読み込みを一握りのドメインに限定していた。ところが、その許可リストにYouTubeが含まれていた。
YouTubeのoEmbedエンドポイント(外部サービスがYouTube動画を埋め込む際に使う仕組み)を利用すると、JavaScriptをレスポンスに乗せて反射させる形で実行できてしまった。CSPの許可リストに含まれるドメインを踏み台にしたCSPバイパスだ。
ステップ4:データ窃取とアカウント乗っ取り
ChatGPT上でJavaScript実行権を得てしまえば、あとは単純だ。OpenAIのプライベートAPIからユーザーデータを取得し、画像参照(imgタグのsrc属性)経由で外部サーバーへ送信するだけでデータの外部流出が完結する。
最終的な攻撃シナリオはこうだ。攻撃者が細工したChatGPTの共有URLを作成し、別のログイン済みユーザーがそのURLを開くだけで、そのユーザーのプライベートデータが盗まれるか、ユーザーになりすました操作が実行される。
OpenAIの対応とバウンティ額への批判
OpenAIはこの脆弱性を修正済みで、Parameter Labsに5,000ドルのバグバウンティを支払った。
Willisonはこの額について「このレベルの深刻な脆弱性にしては安すぎると思う」と率直にコメントしている。なお、Willisonは著名なオープンソース開発者であり、Datasetteの作者として知られる。今回の記事はParameter Labsの元レポートを独自の視点で紹介・解説したものだ。
バウンティ額への批判はコミュニティでも広がっており、攻撃チェーンの複雑さ(MathLive → innerHTML → iframe注入 → YouTubeのCSPバイパス → データ窃取)を考えると、5,000ドルという金額は低いという見方が多い。
実装者へのインプリケーション
今回の攻撃チェーンが示すのは、Artifactsパターンを自前で実装する際のリスクの複雑さだ。サードパーティライブラリの内部実装、CSP許可リストの設計、iframe間のメッセージングの仕様が、それぞれ単独では問題に見えなくても、組み合わさることで致命的な経路を形成しうる。サンドボックス化されたiframeを扱うシステムでは、以下の点が教訓として浮かび上がる。
postMessage()の受信側でinnerHTMLを使うことの危険性——メッセージの送信元を問わずDOM書き換えが可能になる。受信側ではtextContentの使用や、DOMPurifyによるサニタイズを検討すべきだ- CSPの許可リストに含めるドメインの精査——oEmbedのような「JavaScriptを反射できる」エンドポイントを持つドメインは許可してはならない。許可リストは最小権限の原則に従い、定期的に再評価する必要がある
- サンドボックス属性のないiframeを親ページへ注入できる経路の遮断——iframe内から親ページのDOMを操作できる経路がないか、
postMessage()の受信ロジックを網羅的に監査することが不可欠だ
ChatGPTと同種の「AIが生成したHTMLを実行する」機能を実装しているサービスは、同様の経路を点検する価値がある。
詳細はHow We Took Over ChatGPT Accountsを参照していただきたい。