OpenAI の ChatGPT に、公開共有リンクを開いただけで他人のアカウント操作につながる脆弱性があったと、Parameter Labs が報告した。しかも必要だったのは、相手にリンクを踏ませることだけだという。アプリのインストールも、開発者ツールの操作も、コードの貼り付けもいらない。ふだんの共有機能が、そのまま攻撃の入口になり得た、というのがこの話の重さだ。公開されたのは技術検証の詳細だが、そこで描かれているのは「安全に分離されているはずの画面」が、別の部品の連携ミスでつながってしまう典型例でもある。
Parameter Labs が見つけたのは、ChatGPT の共有会話に仕込んだ HTML が、閲覧者の signed-in セッションの中で attacker-controlled JavaScript として動いてしまう経路だった。流れはこうだ。攻撃者はまず、悪意のある会話を ChatGPT で作り、通常の共有機能で公開リンクにする。被害者がそのリンクを開くと、見た目はただの共有会話なのに、裏側ではコードが動き始める。Parameter Labs は、このコードが被害者の会話一覧を列挙し、共有されていない private conversation の内容を取得し、さらに外部サーバーへ送信できることを確認したという。単なる画面改変ではなく、ChatGPT の authenticated APIs を被害者本人として呼び出せる、というのが本質だった。
きっかけは、普通なら無害に見える 2 つの機能だった。ひとつは HTML Preview で、HTML のコードブロックを小さなウェブページとして表示する仕組み。もうひとつは、会話に含まれた graph が内部で読み込む MathLive というライブラリだ。Preview は別のウェブアドレス上の制限された frame の中で動くので、通常は親ページの chatgpt.com を読めない。ところが MathLive は、メインページ側にメッセージ待ち受け口を作っていた。その受け口は postMessage で送られる内容を受け取り、しかも送信元の確認が甘かった。結果として、Preview 側から送ったメッセージで、MathLive の virtual keyboard の layout を差し替えられた。そこに raw HTML を入れられるので、main page の中に HTML を流し込めてしまう。
ただし、そこでまだ JavaScript がそのまま走るわけではない。次に登場するのが iframe の srcdoc だ。HTML を属性として直接埋め込めるこの仕組みは、本来は便利な機能だが、sandbox 属性が付いていなければ別の顔を持つ。ChatGPT の main page がその frame を作ると、ブラウザはそれを chatgpt.com として扱う。つまり、その中のコードは親ページへ手を伸ばせる。最後の壁になったのが Content Security Policy, CSP だった。inline script は止められるが、YouTube の script は許可されていた。Parameter Labs は YouTube の oEmbed にある JSONP 風の callback パラメータを使い、エラー応答の中に JavaScript を混ぜる形で実行に成功した。こうして、元の Preview は分離されたままでも、メインの ChatGPT ページ上で任意コードが走る状態を作り出した。
この研究が実際の攻撃として成立するように、攻撃者側は共有会話の中に graph と HTML Preview を同居させた。graph が MathLive を初期化し、後から来る HTML Preview がメッセージを送る。これで /share/ のリンクひとつが、別ユーザーのセッションに刺さる攻撃手段になる。被害者はリンクを開くか、少なくとも Preview を一度開くだけでよかった。後には自動で Preview する形にもでき、3 回の再現でおよそ 4.5 秒後に alert が出たという。しかもこれは見た目の悪さの話では終わらない。取得できたのは、最近の会話一覧や、未共有の会話本文だったからだ。
この件で一番ぞっとするのは、攻撃の入口が「相手にリンクを開かせる」だけだったことだと思う。セキュリティ事故の話ではしばしば「ユーザーが怪しいファイルを実行した」といった前提がつくが、今回は ChatGPT の通常の共有導線に乗っている。つまり、利用者が警戒すべき対象として最初から見ていない場所に罠がある。しかも、狙われるのは匿名の閲覧者ではなく、ログイン済みの利用者だ。Web アプリとしては最悪に近い組み合わせで、信頼された UI と認証済みセッションが同時に崩れる。
もうひとつ気になるのは、原因が単一のバグではなく、複数の設計の継ぎ目にあったことだ。Preview 自体は分離できていた。CSP も効いていた。YouTube だけ許可されていたのも、単体なら珍しいことではない。ところが、MathLive のメッセージ処理、HTML を layout に流し込む設計、sandbox のない srcdoc、そして許可済みの JSONP がつながった瞬間に、全部が一本の攻撃チェーンになった。こういう事故は「この機能を止めれば終わり」では済まない。似た構造の機能が別の場所に残れば、別ルートでまたつながる可能性がある。だから修正は、ひとつのエンドポイントを塞ぐだけでは足りないはずだ。
今回の話は、sandbox や CSP のような仕組みが無意味だったという意味ではない。むしろ逆で、どちらも一度は正しく働いている。それでも破られたのは、境界の内側にいた別の部品が、境界の外から来た入力を信用してしまったからだ。ここには、ブラウザの防御を過信しすぎると見落としやすい教訓があると思う。防御は一枚岩ではなく、frame、message、HTML、script、そして認証済み API が全部別々に安全でないといけない。
特に気になるのは、こうした攻撃が「表示系の機能」に紛れ込む点だ。graph や HTML Preview は、ユーザー体験を豊かにする機能として見られやすい。だが攻撃者にとっては、任意のコードを差し込む手がかりにもなる。しかも今回のように、正規の共有リンクに載せられるなら、配布も簡単だ。メールでも、チャットでも、SNS でも送れる。防御する側は「怪しいアップロード」だけを見ていても足りない。共有・埋め込み・プレビューの各機能が、どこで同じ権限空間に入るのかを見直さないといけない。
この報告で重要なのは、盗み見られるのがチャット本文に限られないことだと思う。Parameter Labs は会話一覧を列挙し、未共有の会話を取得し、外部へ送れることを示したが、根っこにあるのは authenticated frontend APIs を victim として叩けることだ。つまり、もし ChatGPT の Web 側で別の操作やデータ取得が同じ認証境界に乗っていれば、同じ手口で広がる余地がある。今回の実証は小さく見えるが、実際にはアカウント乗っ取りにかなり近い。
OpenAI が 2026-10-26 に修正し、この報告を P1 と分類したのは妥当だと思う。公開された会話リンクを踏んだだけで、相手のセッション内で勝手に命令を実行できるなら、被害の質が違う。単なる XSS という言葉だけで片づけると軽く見えるが、実際には「共有された会話が認証済みアカウントの操縦桿になる」事故に近い。生成 AI のサービスが日常の仕事に入り込むほど、こうした境界崩壊は深刻になるはずだ。使う側も提供する側も、便利な共有機能を“そのまま信頼してよいもの”として扱わないほうがいい。