配信ソフトOBSのブラウザソースは改ざんサイトの影響を受けるのか実測した
目次

- 検証対象: OBS Studio 32.2.2(現行安定版)および 33.0.0-rc3(リリース候補)のブラウザソース
- 結論: PHPかどうかは関係なく、影響するのは「ブラウザソースのページ権限」「obs-websocketの設定」「内蔵Chromiumの脆弱性+サンドボックス無効」の組み合わせ
- ページ権限(OBS操作): 最大のレベル5(フルアクセス)でもOBSの操作(配信開始・シーン切替等)にとどまり、通常のWebページからローカルファイル読取やOSコマンド実行は通らない
- obs-websocket(外部制御): 有効化かつ認証なしの場合、ブラウザソース内のJavaScriptからでも接続が通り、配信キーの抜き取りやOBS制御につながるリスクがある
- Chromium脆弱性+サンドボックス無効(PC本体侵害): サブプロセスが全件
--no-sandboxで動いており、オーバーレイ側のXSSと内蔵V8の脆弱性(CVE-2024-7971等)が組み合わさるとPC本体でのコード実行に至る
「配信ソフトのOBSは設定によってはPHPの影響を受ける。ブラウザからの操作レベルが高いと、PHP経由でサイトが改ざんされているとそのままOBSも影響を受ける」という話を聞いた。
だがブラウザソースが読み込んで実行するのはHTMLとJavaScriptのはずで、サーバー側のPHPがどう影響するのか、設定されたページ権限でどこまで操作が通るのかが気になった。そこで、手元のWindows 11にOBS Studioのポータブル版を展開し、ブラウザソースのページ権限やobs-websocket、サブプロセスのサンドボックス状態を実際に動かして確かめてみた。
検証環境
Windows 11の環境で、OBS Studioの公式ポータブル版を2つ、既存のインストール版とは別フォルダに展開して使った。
| 版 | 内蔵Chrome/CEF(実測) | 役割 |
|---|---|---|
| OBS 32.2.2 | 127.0.0.6533.120 | 現行の安定版 |
| OBS 33.0.0-rc3 | 150.0.7871.252 | CEF更新版のリリース候補 |
内蔵しているChrome/CEF(Chromium Embedded Framework:アプリ内にブラウザを組み込む仕組み)のバージョンは、libcef.dll に埋め込まれた文字列から確認した。
ブラウザソースには、ローカルに置いたテスト用の確認ページを読み込ませた。このページは、OBSがブラウザソースに注入する操作オブジェクト window.obsstudio に何が含まれるか、権限ごとにどの関数呼び出しが通るかを調べる。さらに、ローカルファイルや外部操作用の通信窓口(ポート4455の制御用ソケット)へアクセスできるかを確かめて結果を表示する作りにした。配信開始などの操作は呼ばず、存在の確認にとどめている。
ブラウザソースの実行経路とPHP
ブラウザソースの中身はChromium(CEF)で、受け取ったHTMLとJavaScriptを描画している。PHPはWebサーバー側で動作してHTMLを生成し終えるため、OBS側が受け取るのは生成済みのHTMLとスクリプトだけになる。テストページの User-Agent も Chrome/127.0.6533.120 OBS/32.2.2 であり、サーバー側がPHP製か静的サイトかはここには現れない。
噂で「PHP」と言われているのは、WordPressなどPHPで動くサイトが改ざん被害に遭いやすいという別の話題が混ざったものと考えられる。改ざんされたページに悪意あるJavaScriptが埋め込まれていれば、それがOBSのブラウザソース内で実行される。この点は静的サイトが改ざんされた場合でも全く同じだ。
ページ権限の仕組み
ブラウザソースには「ページ権限」の設定があり、読み込んだページのJavaScriptがOBSをどこまで操作できるかを6段階で決める。新規ソース作成時の既定値は、下から2番目の「OBSのステータス情報へのアクセス」に設定されている。
| 値 | 名前 | ページから通るようになる操作 |
|---|---|---|
| 0 | None | 権限レベルの確認のみ |
| 1 | ReadObs(既定) | 配信中・録画中かの取得 |
| 2 | ReadUser | シーン一覧・現在のシーン・トランジションの取得 |
| 3 | Basic | リプレイバッファの保存 |
| 4 | Advanced | リプレイ開始停止・シーン切替・トランジション切替 |
| 5 | All | 配信・録画・仮想カメラの開始停止 |
この一覧のどこにも、配信キーの読み出し、OBS設定の取得、任意ファイルの読み出し、OSコマンドの実行は存在しない。権限を最大まで引き上げても、改ざんされたページから実行できる操作は表の範囲にとどまる。
ブラウザソースのプロパティ画面を開くと、既定ではページ権限が「OBSのステータス情報へのアクセス」に指定されている。

必要に応じて、警告付きで「OBSへのフルアクセス」へ切り替えることができる。

権限レベルごとの実測(OBS 32.2.2)
既定のレベル1と最大のレベル5(フルアクセス)で、テスト用ページから同じ呼び出しを試した結果を以下にまとめる。なおポート4455は、OBSを外部操作する内蔵機能(obs-websocket)の通信ポートだ。
| ページ側で試したこと | L1 ReadObs(既定) | L5 フルアクセス |
|---|---|---|
window.obsstudio の注入 | あり | あり |
| 関数名の列挙 | startStreaming 等も含めすべて確認可能 | すべて確認可能 |
付与された権限 getControlLevel | 1 | 5 |
配信中/録画中かの取得 getStatus | 取得成功 | 取得成功 |
シーン情報 getCurrentScene | null(拒否) | 取得成功(シーン 1920x1080) |
シーン切替 setCurrentScene | 実行できず | 実行成功(現在シーンへの無害な指定で確認) |
ローカルファイル読取 file:// | 失敗 | 失敗 |
制御用ソケット ws://127.0.0.1:4455 | 接続不可 | 接続不可 |
関数の名前自体はどのレベルでも列挙できるが、呼び出しが実際に通るかは権限レベルで制限されている。レベル1では配信状態の取得までで、シーン情報の取得やシーン切替は拒否された。レベル5に上げると、シーン情報の取得やシーン切替が通り、配信・録画・仮想カメラの操作用関数も実行できる状態になった。
テスト用ページで権限レベル5を実行した際の結果画面が以下だ。

一方で、権限を最大にしてもローカルファイルの読み取りと制御用ソケットへの接続は失敗したままだった。この2つはページ権限APIの対象外であり、レベルを上げてもアクセスできない。改ざんされたオーバーレイにフルアクセスを与えてしまうと、勝手に配信を停止する・録画を開始する・シーンを切り替える、といった妨害は行える。ただし、OBSの設定奪取やPC本体を乗っ取られる事態とは影響の範囲が異なる。
サブプロセスのサンドボックス状態
PC本体への侵入に関わるのが、Chromiumのサンドボックス状態だ。OBSのブラウザソースは内部でChromiumのレンダラー(Webページの描画やJavaScriptの実行を担当するプロセス)を分離して動かす。しかし、このプロセスのサンドボックスが無効化されていると、レンダラーが脆弱性によって侵害された際にホストPCへ影響が及びやすくなる。
稼働中のOBS 32.2.2において、ブラウザサブプロセスの起動引数を確認した。
| サブプロセス | サンドボックス引数 |
|---|---|
| レンダラー ×2(ページのJavaScriptを実行) | --no-sandbox |
| gpu-process ×1 | --no-sandbox |
| utility ×2 | --no-sandbox |
すべてのサブプロセスに --no-sandbox が付与されていた。OBSのソースコード上の設定(settings.no_sandbox = true)どおり、稼働中プロセスの引数からもレンダラーのサンドボックスが無効であることが確認できた。
32.2.2で報告された実害の攻撃手順
2024年9月に、Orange Cyberdefense SwitzerlandのSCRTが、OBS Studioでの実証手順を公開している。視聴者が入力したチャット内容を無害化(サニタイズ)せずにそのままHTMLとして表示するオーバーレイにおいて、XSS(悪意あるスクリプトの注入)が発生する。さらに、内蔵されていたCEF(V8エンジン)の型混同の脆弱性 CVE-2024-7971 を突くことで、配信PC上でのネイティブコード実行(任意のプログラム実行)に至るという攻撃手順だった。CVE-2024-7971はOBS固有のバグではなく、Chrome 128で修正済みのV8の脆弱性だが、OBS 32.2.2が内蔵していたChromium 127にはパッチが適用されていなかった。
この手順では、ブラウザソースのページ権限設定は関係しない。前提となるのは、視聴者が入力できるテキストを無害化せずに描画するオーバーレイを使用している点だ。そして、レンダラーのサンドボックスが無効化されていたことが、ブラウザ内の脆弱性をホストPC上でのコード実行へと直結させている。
obs-websocket有効化時のソケット接続
obs-websocketは、WebSocketを通じてOBSを外部ツール(Stream Deck等)から操作する内蔵機能で、既定ポートは4455に設定されている。既定では無効になっており、前述の実測でも接続できなかった。これを有効化し、ブラウザソースのテストページから接続できるか確かめた。
| ページ側から試した操作 | 有効化前 | 有効化後 |
|---|---|---|
ws://127.0.0.1:4455 への接続 | 接続不可 | 接続成功 |
http://127.0.0.1:4455 への要求 | 失敗 | 応答あり |
ローカルファイル読取 file:// | 失敗 | 失敗 |
有効化したところ、通常のWebオリジンにすぎないテストページからでも、ポート4455へのソケット接続が確立した。接続段階でオリジンを検証して拒否する仕組みにはなっていない。
obs-websocketの設定画面では、サーバーの有効化と認証パスワードを設定できる。

ただし、ソケット接続が通る=即座にOBSを操作できる、というわけではない。認証設定によって動作は次のように分かれる。
| 認証設定 | ソケット接続時の挙動 |
|---|---|
| 認証あり(既定) | 接続は確立するが認証要求で止まり、パスワードを持たない改ざんページからは操作できない |
| 認証なし | 接続直後から操作を受け付けるため、ページ側からOBSを自由に制御される危険がある |
特に認証なしの状態では注意が必要だ。obs-websocket v5 の仕様では、GetStreamServiceSettings リクエストを通じて配信サーバーURLやストリームキーを取得できる。認証を切ってしまうと、改ざんされたオーバーレイから配信キーを抜き取られるリスクが生じるため、認証は有効のまま運用する必要がある。
ローカルファイル指定時の読取可能範囲
ブラウザソースには、Web上のURLではなくローカルのHTMLファイルを指定する「ローカルファイル」機能がある。この設定で読み込ませた場合にアクセス可能な範囲を確かめた。
ローカルファイルを読み込んだページのオリジンは http://absolute となり、file:// スキームそのものでは動作しない。OBSはローカルファイルを http://absolute/ 配下のオリジンに対応付けて読み込んでいる。
| ページ側から試した読み取り | 結果 |
|---|---|
| 同じフォルダ内のファイル(相対パス) | 成功 |
システム領域(file:///C:/Windows/win.ini) | 失敗 |
絶対パス指定(file:// の絶対URL) | 失敗 |
テストページをローカルファイルとして読み込んだ際の結果が以下だ。

ローカルファイル指定のオーバーレイは、自身が配置されたフォルダ内のファイルであれば相対パスで読み取ることができた。一方で、file:// の絶対パスを用いてシステム領域のファイルを読み出すことはできない。オリジンが http://absolute となるため、file:// へのリクエストは別スキームとして遮断される。
読み取り可能な範囲はオーバーレイ自身のフォルダ内に限られ、任意のシステムファイルにはアクセスできない。また、リモートの改ざんページがブラウザソースのローカルファイル設定を外部から有効化することもできない。
OBS 33.0.0-rc3(CEF 150)での検証
CEFのバージョンを127から150へ更新したリリース候補版(33.0.0-rc3)でも同様の確認を行った。ブラウザソースの User-Agent は Chrome/150.0.7871.252 OBS/33.0.0 に更新されている。
権限レベル5(フルアクセス)における実行結果は、32.2.2と同様だった。
| ページ側で試したこと | 32.2.2(L5) | 33.0.0-rc3(L5) |
|---|---|---|
付与された権限 getControlLevel | 5 | 5 |
配信中/録画中かの取得 getStatus | 取得成功 | 取得成功 |
シーン情報 getCurrentScene | 取得成功 | 取得成功(シーン 1920x1080) |
シーン切替 setCurrentScene | 実行成功 | 実行成功 |
ローカルファイル読取 file:// | 失敗 | 失敗 |
33.0.0-rc3のテストページ画面でも、Chrome 150環境で権限レベル5が動作し、file:// の読み取りは遮断されている。

サブプロセスの起動引数についても、32.2.2と同様に全サブプロセスへ --no-sandbox が付与されていた。
| サブプロセス | 32.2.2 | 33.0.0-rc3 |
|---|---|---|
| レンダラー ×2 | --no-sandbox | --no-sandbox |
| gpu-process ×1 | --no-sandbox | --no-sandbox |
| utility ×2 | --no-sandbox | --no-sandbox |
CEFを150へ更新しても、サンドボックス無効の設定自体は継続している。更新によって得られるのはChromium側の既知の脆弱性修正(CVE-2024-7971等への対策)であり、サンドボックス自体の無効化は別の設計として残っている。
なお、33.0.0-rc3でのobs-websocket接続については、ポート4455を先に起動していた32.2.2が占有していたため、独立した挙動検証からは除外した。
配信者側で取れる対策
- オーバーレイの入力をサニタイズする: 視聴者のチャットや名前をそのままHTMLとして描画せず、テキストとして適切にエスケープしてXSSを防ぐ。
- 信頼できない外部URLを読み込まない: 管理の不透明な外部サイトや、第三者が改ざん可能なURLをブラウザソースに設定しない。
- ページ権限は必要最小限に留める: 配信制御が必要なウィジェット以外は、既定のレベル1(ステータス取得のみ)を維持する。
- obs-websocketの認証を維持する: obs-websocketを利用する際は必ずパスワード認証を有効にし、無認証での開放を避ける。
- OBSの更新を適用する: Chromium/CEFの更新が含まれるバージョンへアップデートし、内蔵ブラウザの既知の脆弱性を塞いでおく。