ProxyOrbを構築するにあたって、あらゆる設計上の判断で根本的なパラドックスに直面しました。Webプロキシとはブラウザにサードパーティのコンテンツを同一オリジンのコンテンツだと思い込ませることで成立するサービスです。つまり定義上、ブラウザのコアセキュリティモデルを欺くものです。ところがモダンブラウザは、まさにこの種のオリジン混同に対して、15年かけて巧妙な防衛機構を何層にも積み重ねてきました。
この記事では、その緊張関係をファーストプリンシプルから掘り下げます。Webプロキシが同一オリジンポリシーと実際にどう相互作用するのか――概念レベルではなく、HTTPヘッダー・Chromiumのソースコード・プロダクションエンジニアリングのトレードオフという実装レベルで理解したいセキュリティ研究者、ペネトレーションテスター、ブラウザセキュリティエンジニアの方に向けた内容です。
SOP の基礎、URL rewriting、CORS、CORB/CORP、COEP/COOP、Service Worker、iframe、そしてプロキシ事業者とユーザー双方へのセキュリティ上の影響について説明します。
1. 同一オリジンポリシーの基礎
同一オリジンポリシー(SOP)は スキーム + ホスト + ポート の3つ組で定義されます。2つの URL が同一オリジンとみなされるのは、この3要素がすべて完全に一致する場合のみです。https://example.com:443 と http://example.com:80 は同じサーバーを指していても、クロスオリジンとして扱われます。
SOP が実際に何を防ぐかと何を許可するかは、よく誤解されています。SOP は以下をブロックしません。
- オリジンをまたいだ画像の読み込み(
<img src>) - オリジンをまたいだスクリプトの読み込み(
<script src>) - オリジンをまたいだスタイルシートの読み込み(
<link rel="stylesheet">) - オリジンをまたいだ iframe の埋め込み(ただし埋め込まれたドキュメントの内容は隔離されます)
- オリジンをまたいだフォーム送信(
<form action>)
SOP が防ぐのは、fetch() や XMLHttpRequest 経由のクロスオリジンリクエストに対するレスポンスの読み取りです。リクエスト自体はネットワークに送出されますが、異なるオリジンで動作する JavaScript からはレスポンスボディとヘッダーが隠蔽されます。
この違いは、Webプロキシにとって非常に重要です。プロキシの役割は、プロキシサーバーとターゲットサーバーという2つのオリジンを1つにまとめ、クロスオリジン境界を解消することです。すべてのリソースが https://proxyorb.com から配信されているように見えれば、SOP によるレスポンスの読み取り制限はそもそも発動しません。
Webプロキシが活用する「合法的な空間」が URL rewriting です。https://example.com/api/data の代わりに、すべてのリクエストが https://proxyorb.com/api/data?__pot=aHR0cHM6Ly9leGFtcGxlLmNvbQ== という形式になります。ブラウザの視点では、これは同一オリジンへのリクエストです。SOP が回避されているのではなく、すべてのコンテンツのオリジンを変更することで SOP を無意味にしているのです。
2. ProxyOrb の URL Rewriting アーキテクチャ
セキュリティ上の影響を理解するには、エンコーディングの仕組みを把握する必要があります。ProxyOrb は __pot(proxy origin token)というURLパラメータを使用し、Base64エンコードされたターゲットオリジンを格納します。
__pot パラメータ
__pot パラメータには常にターゲットのオリジン(スキーム + ホスト、パスなし)がエンコードされており、完全な URL ではありません。つまり https://example.com/some/deep/path?foo=bar と https://example.com/other/page は同じ __pot 値 aHR0cHM6Ly9leGFtcGxlLmNvbQ==(https://example.com を Base64エンコードしたもの)を生成します。実際のパスとクエリ文字列は、プロキシURL自身のパスとクエリ文字列にそのまま保持されます。
ユーザーが https://proxyorb.com/?__pot=aHR0cHM6Ly9leGFtcGxlLmNvbQ== にアクセスすると、ゲートウェイがそれをデコードして元の URL を再構築します。
ゲートウェイはリクエストを実際のターゲットサーバーへ転送する際、Origin ヘッダーを書き換えて、上流サーバーがプロキシドメインではなく自身のドメインを受け取るようにします。
Service Worker によるクライアントサイドURL Rewriting
ゲートウェイはサーバーサイドを処理します。クライアントサイド――HTML・JavaScript・CSS レスポンス内の URL を書き換えて、すべてのサブリクエストが引き続きプロキシを経由するようにする処理――は Service Worker が担います。
プロキシ 仕組みの核心となる変換処理は、ページコンテンツ内で見つかったあらゆる URL をプロキシ形式に変換します。
例えば、プロキシ経由で表示されているページ内で参照されている https://cdn.example.com/bundle.js は、https://proxyorb.com/bundle.js?__pot=aHR0cHM6Ly9jZG4uZXhhbXBsZS5jb20= に変換されます。
この書き換えは包括的であり、fetch()、XMLHttpRequest、<script src>、<img src>、WebSocket 接続、<link> タグをすべてカバーします。ページ内のすべての URL がプロキシオリジンを指すようになると、ブラウザはクロスオリジンリクエストを一切行いません――すべてのリクエストが構造上、同一オリジンになるからです。
フルナビゲーションなしでの __pot 復元
プロキシされたページの内部から発生するリクエストが __pot パラメータを持たないというエッジケースが存在します。例えば、Service Worker が URL を書き換える前に発火する相対パスの fetch('/api/data') や、URL リライターをバイパスした動的インジェクトスクリプトが発したリクエストなどです。
Service Worker は、カスケードルックアップによってトークンを復元します。
ゲートウェイにも並列の復元パスがあります。__pot なしでリクエストが届いても、Referer ヘッダーが __pot を含む同一オリジン URL を指している場合、ゲートウェイはリファラーからトークンを抽出して現在のリクエストに付加します。ゲートウェイが受け取る前にページ自身の JavaScript によってトークンが除去されるナビゲーションシナリオに対応するためです。
3. CORS:明示的なクロスオリジン許可システム
CORS(Cross-Origin Resource Sharing)は、サーバーが特定のレスポンスヘッダーを送信することで、クロスオリジンアクセスへのオプトインを可能にする仕組みです。プロキシの観点では、CORS は2種類の問題を引き起こします。
問題1:CORSプリフライトのインターセプト
ページ上の JavaScript が非シンプルヘッダー(例:Authorization、Content-Type: application/json)を含む fetch() リクエストを行うと、ブラウザはまず OPTIONS プリフライトリクエストを送信します。ターゲットサーバーのプリフライトレスポンスに許可的な CORS ヘッダーが含まれていなければ、実際のリクエストはブロックされます。
ProxyOrb のアーキテクチャでは、Service Worker がすべての OPTIONS リクエストをインターセプトし、ゲートウェイに届く前に合成レスポンスを返すことで、実際のリクエストをアンブロックします。
ゲートウェイレベルでは、すべてのプロキシレスポンスに同等の CORS ヘッダーが付与されます。
問題2:認証情報付きリクエスト
Access-Control-Allow-Credentials: true とワイルドカードでない Access-Control-Allow-Origin の組み合わせは重要です。CORS では、認証情報が含まれる場合、* ではなく明示的なオリジン値が必要です。Service Worker はすべての送信リクエストを credentials: 'include' で発行するため、ゲートウェイはワイルドカードではなく、リクエスト元の正確なオリジンをエコーバックしなければなりません。
これにより、ユーザーがプロキシ経由で訪問したすべてのターゲットサイトで蓄積された proxyorb.com 配下のクッキーが、すべてのプロキシリクエストに送信されることになります。これはセッション状態を維持するための意図的な仕様ですが、第8節で詳述するセキュリティ上の重要な考慮事項でもあります。
CORS ヘッダーの削除と置換パターン
プロキシされたレスポンスには、ターゲットサーバーから送信された CORS ヘッダーが含まれている場合があります。これらはブラウザの視点では誤った内容です(プロキシオリジンではなくターゲットオリジンを参照しています)。Service Worker はそれらを削除して置換します。
4. CORB と CORP:Chromium のより厳格な防衛
CORS はサーバー側からの明示的なオプトインで機能します。Chromium はこれとは別に、CORS 設定に関係なくデフォルトで有効な2つのメカニズムを追加しています。
Cross-Origin Read Blocking(CORB)
CORB は Spectre 対策の一環として Chrome 67(2018年)で導入されました。核心にある洞察はこうです。クロスオリジンレスポンスのボディが JavaScript に読み取られないとしても、それがレンダラープロセスでフェッチ・デコードされた時点で、そのプロセスのアドレス空間に存在します。Spectre クラスの攻撃はサイドチャネル経由でそれを抽出できます。
CORB は特定のクロスオリジンレスポンスがレンダラープロセスに入ることを防ぎます。具体的には、<script> タグや <img> タグがクロスオリジンレスポンスをフェッチし、そのレスポンスの Content-Type が text/html、text/xml、または application/json である場合、Chromium はボディを検査し(CORB 仕様で定義された MIME タイプスニファーを使用)、タイプが一致すれば、レンダラーが見る前にレスポンスを空のものに差し替えます。
Webプロキシ セキュリティの観点では、リクエストが実際にクロスオリジンであれば CORB は壊滅的な影響をもたらします。<script> タグから取得した application/json を返す API エンドポイントは、無音のまま空を返すでしょう。しかし ProxyOrb はすべての URL を同一オリジンに書き換えるため、CORB のクロスオリジン条件は発動しません――ブラウザからは、すべてのレスポンスが proxyorb.com から来るように見えるからです。
CORB が問題になるのは、Service Worker が完全に登録されてリクエストをインターセプトする前の移行期間です。その窓で URL rewriting をすり抜けたリクエストがあれば、CORB がそれをブロックする可能性があります。このレースコンディションこそが、ProxyOrb がメインスレッドのインターセプターレイヤーも維持している理由です。このレイヤーは、XMLHttpRequest、fetch、DOM 属性セッターをページ JavaScript の実行前に同期的にパッチし、Service Worker 起動中のフォールバックを提供します。
なお、CORB は Opaque Response Blocking(ORB)によって部分的に置き換えられつつあります。Chromium が導入を進めているこの仕様は、Spectre 保護を維持しつつ誤検知を減らすよう CORB のルールを洗練させたものです。プロキシの互換性への影響は同様です。
Cross-Origin Resource Policy(CORP)
CORP は Fetch 仕様で定義されており、サーバーが自らのリソースを同一オリジンまたは同一サイトのコンテキストからのみ読み込まれるように宣言できます。
Chromium がクロスオリジンのサブリソースリクエストでこのヘッダーに遭遇すると、レスポンスを完全にブロックします。これは CORB より攻撃的で、コンテンツタイプに関係なく適用され、MIME スニッフィングでもバイパスできません。
繰り返しになりますが、ProxyOrb の URL rewriting によってブラウザからはすべてのリクエストが同一オリジンに見えるため、ターゲットサーバーの CORP ヘッダーはブロックを引き起こしません。ゲートウェイはまた、URL rewriting をすり抜けたエッジケースに備えて、レスポンスからこれらのヘッダーを防御的に削除します。
CORP のより深い問題は、実はプロキシアーキテクチャが互換性を助けるケースです。https://api.example.com と https://www.example.com の両方がプロキシされている場合、どちらも同じプロキシオリジンにマッピングされるため、一方から他方へのフェッチは真の同一オリジンとなり、CORP の制限がそれらの間には適用されなくなります。
5. COEP と COOP:クロスオリジン分離
Chrome 92(2021年)以降、SharedArrayBuffer へのアクセス――ひいては特定のパフォーマンス API で使用される高精度タイマー――は、クロスオリジン分離にオプトインしたページのみに制限されました。このオプトインには、連携して機能する2つのレスポンスヘッダーが必要です。
Cross-Origin-Embedder-Policy(COEP)
ページがこのヘッダーを送信すると、ブラウザはそのページが読み込むすべてのサブリソースに対して、以下のいずれかを要求します。
- 同一オリジンである、または
- 明示的に
Cross-Origin-Resource-Policy: cross-originを送信している、または - 認証情報付きフェッチに対して許可的な CORS レスポンスを返す
Webプロキシにとっての問題点:ターゲットサイトがメインドキュメントに COEP: require-corp を送信し、そのドキュメントがヘッダーを保持したままプロキシ経由で配信された場合、ブラウザはそのページが読み込むすべてのサブリソースにもオプトインを要求します。オプトインしていないリソース――大半はそうです――はネットワークエラーになります。
Cross-Origin-Opener-Policy(COOP)
COOP は、ページがクロスオリジンページとブラウジングコンテキストグループを共有できるかどうかを制御します。same-origin に設定されると、クロスオリジンナビゲーションは新しいブラウジングコンテキストグループを開き、window.opener 参照とページ・クロスオリジンオープナー間の postMessage チャネルが切断されます。
プロキシにとって、COOP は COEP ほど即座に破壊的ではありませんが、クロスオリジンの postMessage フロー(最も一般的な例は OAuth ポップアップフロー)に依存するサイトは壊れます。
プロキシ事業者のジレンマ
これは ProxyOrb における最も困難なトレードオフです。
オプション A:レスポンスから COEP と COOP を削除する。
- メリット:サブリソースの読み込みが正常に機能し、プロキシされたページはこれらの制限を適用しない。
- デメリット:ターゲットサイトが意図的に設定したセキュリティヘッダーを削除することになる。サイトが Spectre クラスの攻撃から機密データを保護するためにクロスオリジン分離を使用していた場合、これらのヘッダーを削除するとそのリスクが再び露出する。
オプション B:COEP と COOP を保持する。
- メリット:ターゲットサイトのセキュリティ意図が尊重される。
- デメリット:
CORP: cross-originを明示的に設定していないサブリソースは読み込みに失敗し、ほとんどの複雑な Web アプリケーションが壊れる。
ProxyOrb の現在の戦略はオプション Aです。ゲートウェイはレスポンスから Cross-Origin-Embedder-Policy と Cross-Origin-Opener-Policy を削除します。これはサイト互換性を最大化します。セキュリティのトレードオフは意識的に行われています。Webプロキシのユーザーは、意図されたデプロイコンテキストとは異なる環境でコンテンツを実行することを受け入れているのです。
ブラウザの新しいセキュリティメカニズムはパターンに従います。オプトイン(保護を望むサイトがヘッダーを送信できる)として導入され、やがて新しい API のデフォルトとなり、最終的には強制適用が検討されます。COEP はこの道を歩みました。Chrome 83 ではオプショナル、Chrome 91 では SharedArrayBuffer に必須となりました。サードパーティコンテンツを調整なしに埋め込んでいたサイトは、コンテンツが壊れることに気づきました。Webプロキシはその定義上、サードパーティコンテンツを仲介するため、この問題をさらに複雑にします。
ブラウザセキュリティコミュニティはこの問題を認識しています。新興の Document-Isolation-Policy 提案は、プロセス分離をクロスオリジン分離要件から切り離すことを目指しており、すべてのサブリソースのオプトインを必要とせずに Spectre 対策を得ることを可能にするかもしれません。それが実装されれば、分離ヘッダーとのプロキシ互換性が改善される可能性があります。
6. ブラウザサイドの信頼レイヤーとしての Service Worker
Service Worker は単なる最適化ではありません――ProxyOrb のセキュリティモデルにとってアーキテクチャ上不可欠な存在です。その理由を説明します。
登録スコープはオリジンに紐付く
Service Worker は、登録ページのオリジン内に収まる scope で登録されます。ProxyOrb が Service Worker を登録すると、スコープは https://proxyorb.com/ となり、そのオリジン配下のすべてのページからのフェッチをインターセプトします。
これが URL rewriting によって同一オリジン化が機能する根本的な理由です。SW がクライアントを制御下に置いた後は、ページ内の JavaScript がどの URL をフェッチしようとしても、すべてのネットワークリクエストはまず Service Worker を通過します。
インターセプションパイプライン
Service Worker がリクエストをインターセプトすると、複数の判断ステージを経ます。
透過的なヘッダー転送
1つの微妙な課題があります。ブラウザは Fetch API 経由で特定の「禁止された」リクエストヘッダー(Host、Origin、Referer など)を JavaScript が設定することを制限しています。Service Worker はこれを回避するため、制限されたヘッダーを単一のカスタムパススルーヘッダーにエンコードします。ゲートウェイはそれをデコードし、ターゲットサーバーへ転送する前に適用します。
信頼できる仲介者としての SW のセキュリティ上の意味
セキュリティの観点から見ると、Service Worker はスコープ内のあらゆるページからのリクエストを検査・変更・偽造できる特権的な立場を占めています。正規のプロキシ用途ではこれがまさに目的です。しかし悪意あるプロキシにとっては、これは非常に強力な攻撃対象領域となります。
だからこそ、Service Worker スクリプト自体の信頼性が最重要です。ProxyOrb はインターセプタースクリプトを、厳格なキャッシュコントロールを設定した HTTPS 経由で自身のオリジンから配信しています。攻撃者が改ざんされた Service Worker を注入できれば、影響を受けるユーザーのすべてのトラフィックをインターセプトできます――プロキシトラフィックだけでなく、そのオリジン配下のページからのあらゆるリクエストが対象になります。
7. iframe:フレーム祖先問題
iframe は通常のサブリソースとは異なる課題をもたらします。独自のナビゲーション・独自の SOP 境界・独自の埋め込み制限を持つネストされたブラウジングコンテキストが関与するからです。
X-Frame-Options と frame-ancestors
ページが iframe に埋め込まれることを防ぐ2つのメカニズムがあります。
レガシー: X-Frame-Options: DENY または X-Frame-Options: SAMEORIGIN
モダン: Content-Security-Policy: frame-ancestors 'none' または frame-ancestors 'self'
ゲートウェイがこれらのいずれかを送信するターゲットページをプロキシする場合、そのページをプロキシオリジン配下の iframe に埋め込むことはできません。X-Frame-Options: SAMEORIGIN はターゲットオリジン(example.com)を参照し、プロキシは proxyorb.com からページを提供するため、ブラウザの同一オリジンチェックが失敗します。
プロキシはプロキシされたレスポンスからこれらのヘッダーを削除し、CSP を許可的なバージョンに置き換えなければなりません。
iframe のインターセプトとスクリプトインジェクション
埋め込まれた iframe は第二の問題を提起します。コンテンツはプロキシから読み込まれますが、iframe のブラウジングコンテキストには自動的に Service Worker もメインスレッドのインターセプターもアクティブになりません。プロキシされたページが <iframe src="https://widget.example.com/..."> を作成する場合、その iframe URL もプロキシ形式に書き換えられ、プロキシのインターセプタースクリプトを iframe ドキュメントに注入する必要があります。
iframe インターセプターは2つのレベルで動作します。
レベル1 — プロトタイプパッチ(プログラムによる iframe 作成をキャッチ):
レベル2 — MutationObserver フォールバック(DOM に挿入された iframe をキャッチ):
sandbox 属性の問題
HTML の sandbox 属性は iframe が実行できることを制限します。sandbox="allow-scripts allow-same-origin" はスクリプト実行、フォーム送信、クロスオリジンアクセスなどを制御します。プロキシインジェクションが機能するには、iframe がスクリプトを実行でき、親のプロキシコンテキストにアクセスできる必要があります。
allow-same-origin トークンは特に微妙です。allow-scripts とともに存在する場合、サンドボックスのオリジン分離を無効化し、iframe が埋め込みページのオリジンで実行されます。存在しない場合、iframe は一意の不透明なオリジンを取得し、プロキシスクリプトのインジェクションが完全に壊れます。
ProxyOrb の sandbox 属性に対する現在のアプローチは、プロキシスクリプトを注入する前に sandbox 属性を完全に削除することです。
これは重大なセキュリティトレードオフです。サンドボックスは元のサイトが埋め込みコンテンツの機能を制限するために意図的に設置したものです。それを削除すると、そのコンテンツができることが拡張されます。エンドユーザーには見えませんが、プロキシセッションのセキュリティ態勢に実質的な影響を与える判断です。
8. プロキシ事業者へのセキュリティ上の影響
攻撃対象領域の全体像
ユーザーが ProxyOrb を通じてブラウズする際、いくつかのカテゴリの機密データがプロキシのオリジンを流れます。
セッションクッキー:すべてのターゲットサイトが proxyorb.com 経由でプロキシされるため、クッキーはそのオリジン配下に保存されます。銀行、メール、ソーシャルメディアでの認証済みセッションはすべて、単一ドメイン配下のクッキーになります。Service Worker の credentials: 'include' は、これらのクッキーがすべてのプロキシリクエストに付随することを意味します。
Referer ヘッダー:上流サーバーに送信される Referer ヘッダーは、ユーザーが閲覧していたページを露出させます。プロキシは上流サーバーへ転送する前に referer 値から自身のドメインを慎重に除去します。リクエストが https://proxyorb.com/some/path?__pot=... から発生した場合、送信 Referer ヘッダーは元のターゲット URL(https://example.com/some/path)として再構築されます――プロキシドメインが上流サーバーに漏洩することはありません。
JavaScript 実行コンテキスト:プロキシ経由で提供されるすべての JavaScript ファイルは変更(URL 書き換え)され、プロキシのオリジンで実行されます。ProxyOrb を通じてプロキシされた evil.example.com の悪意あるスクリプトは proxyorb.com オリジンで実行され、そのオリジンのローカルストレージ、クッキー、IndexedDB へのフルアクセスを持ちます――これには、ユーザーがプロキシ経由でアクセスした他のすべてのターゲットサイトのデータが含まれます。
悪意あるプロキシの脅威モデル
教育目的で、悪意あるプロキシができることで ProxyOrb が意図的にしないことを明示する価値があります。
-
認証情報の収集:悪意あるプロキシはゲートウェイを通過するすべてのリクエストボディ(パスワードやフォームデータを含む)をログに記録できます。
-
セッションハイジャック:すべてのターゲットサイトのクッキーがプロキシドメイン配下に保存されているため、悪意あるプロキシ事業者はゲートウェイ経由でサーバーサイドからそれらのクッキーにアクセスできます。
-
コンテンツインジェクション:プロキシは必然的にページコンテンツを変更します(Service Worker を注入し URL を書き換えるため)。悪意あるプロキシは任意の JavaScript――キーロガー、クリプトマイナー、広告詐欺スクリプト――をユーザーに気づかれずに注入できます。
-
SSL ストリッピング:プロキシがゲートウェイからユーザーへの区間で HTTPS 接続を HTTP にダウングレードすれば、すべてのトラフィックが平文になります。
ProxyOrb はエンドツーエンドで HTTPS で運用され、リクエストボディをログに記録しません。Webプロキシの事業者はこれらの能力を持っており、信頼できるプロキシ事業者を選ぶことは、信頼できる VPN プロバイダーを選ぶことと同程度に重要です。
混在コンテンツ
モダンブラウザは混在コンテンツブロッキングを適用します。HTTPS ページは HTTP サブリソースを読み込めません。ProxyOrb はゲートウェイからの送信接続をすべて HTTPS に強制することでこれを処理します(ターゲット URL が HTTP を使用していても同様)。CSP オーバーライドには upgrade-insecure-requests が含まれており、ブラウザに HTTP サブリソース URL を読み込む前に HTTPS にアップグレードするよう指示します。
これは一般的に望ましいことですが、意図的に HTTP でリソースを提供しているサイト(レガシー CDN、ローカルホストリソースなど)が壊れる可能性があります。
9. 続く軍拡競争:おわりに
ProxyOrb の構築を始めたとき、主な互換性の課題は CORS と X-Frame-Options でした。それ以来、Chromium は CORB、CORP、COEP、COOP を実装し、Document-Isolation-Policy を開発中です。進行方向は明確です。ブラウザはクロスオリジン境界の適用においてますます積極的になっており、新しいメカニズムごとにプロキシインフラが適応を求められます。
最も重要な今後の課題は、主要な Web アプリケーション全体への COEP の完全展開でしょう。パフォーマンスのために SharedArrayBuffer を使用するサイト(動画エディター、IDE、コラボレーションツール)は COEP: require-corp をますます設定するようになっています。ProxyOrb が互換性を維持するためにこのヘッダーを削除するため、COEP が有効にする高パフォーマンス機能を必要とするユーザーは、プロキシコンテキストでそれらが低下することに気づくでしょう。
セキュリティ研究者にとって、プロキシアーキテクチャは重要なことを明らかにします。同一オリジンポリシーはファイアウォールではありません。それは URL 構造に基づく信頼のモデルです。Webプロキシは、SOP が「これら2つのリソースは正当に同一オリジン」と「これら2つのリソースは同一オリジンに見えるよう URL 書き換えされた」の間に本質的な区別を設けないという事実を利用します。SOP 上のブラウザセキュリティスタック全体――CORS、CORB、CORP、COEP、COOP――は、URL ベースのオリジン同一性より堅牢な防衛を追加する試みと見なすことができます。
これを理解することは、プロキシサービスを監査する人、ブラウザセキュリティポリシーを設計する人、プロキシ経由でアクセスされる可能性があるアプリケーションの実際のセキュリティ態勢を評価する人すべてにとって不可欠です。
よくある質問(FAQ)
Webプロキシは同一オリジンポリシーをバイパスしますか?
正確にはそうではありません。Webプロキシは URL rewriting によって動作します。すべてのクロスオリジン URL を同一オリジン URL に変換し、SOP のクロスオリジン制限を回避するのではなく無関係にします。ブラウザの視点からは、すべてのコンテンツがプロキシ自身のオリジンから来るように見えるため、クロスオリジン境界は越えられません。これはアーキテクチャ上バイパスとは異なります――SOP は依然としてそのルールを適用していますが、プロキシはそれらのルールが発動しないようにコンテンツを設計しているのです。
CORS は Webプロキシサーバーにどのような影響を与えますか?
CORS はプロキシサーバーに2つのレベルで影響を与えます。まず、プロキシは OPTIONS プリフライトリクエストをインターセプトし、許可的な CORS ヘッダーで応答しなければなりません。実際のターゲットサーバーのプリフライトレスポンス(ターゲットオリジンを参照)はプロキシオリジンに対するブラウザの CORS チェックを満たさないからです。次に、プロキシはターゲットサーバーレスポンスの CORS ヘッダーを削除し、プロキシオリジンを参照するヘッダーに置き換えなければなりません。Access-Control-Allow-Credentials: true の設定は、Service Worker の credentials: 'include' と組み合わさり、プロキシのオリジンからのすべてのクッキーがすべてのプロキシリクエストに付随することを意味します。
CORB とは何で、プロキシサービスにどのような影響を与えますか?
CORB(Cross-Origin Read Blocking)は、クロスオリジンのサブリソースとして読み込まれた場合、特定の機密なクロスオリジンレスポンス(HTML、JSON、XML)がレンダラープロセスに入ることを防ぐ Chromium の防衛機能です。正しく設定された Webプロキシでは、URL rewriting がすべてのリクエストを同一オリジンにするため、CORB は一般的に発動しません。しかし CORB は、Service Worker が完全に登録される前の期間に問題を引き起こす可能性があります。その際、一部のリクエストが URL rewriting をすり抜けて真のクロスオリジンリクエストとして送信される場合があります。CORB は Spectre 対策として導入され、WHATWG Fetch 仕様で定義されています。
WebプロキシはHTTPオンリークッキーにアクセスできますか?
できません。HttpOnly クッキーはターゲットサーバーによって設定され、Service Worker で動作する JavaScript を含む JavaScript から読み取れません。ただし、ゲートウェイはユーザーの代わりにリクエストを転送する際、ブラウザがリクエストヘッダーにクッキーを送信するため、これらのクッキーを受け取ります。HttpOnly フラグはクライアントサイドの JavaScript による窃取を防ぎますが、プロキシサーバー自体が転送中のクッキー値を見ることを防ぎません。これは HttpOnly が XSS を防ぐがサーバーサイドのインターセプトは防がないという点と同様です。
ブラウザセキュリティの観点から Webプロキシの使用は安全ですか?
脅威モデルによります。ブラウザの観点からは、Webプロキシ経由で提供されるすべてのコンテンツはプロキシのオリジンで実行されます。つまり、プロキシされたサイトの1つの JavaScript の脆弱性が、別のプロキシされたサイトのセッションデータに潜在的にアクセスできる可能性があります(同じオリジンのクッキージャーとストレージを共有するため)。プロキシの事業者も、転送中のすべてのトラフィックへのアクセスを持つ信頼された当事者です。制限された環境で機密性の低いコンテンツにアクセスするためのリスクは、一般的に許容できます。機密性の高いサービス(銀行、医療、政府)での認証済みセッションには、プロキシ事業者がそのトラフィックを観察する技術的能力を持つことをユーザーは理解すべきです。そして、監査可能なノーログポリシーと強固な運用セキュリティを持つプロキシサービスのみを使用すべきです。
本記事は2026年初頭時点の ProxyOrb のアーキテクチャを反映しています。ブラウザのセキュリティメカニズムは急速に進化します。最新情報については、WHATWG Fetch Standard、W3C Content Security Policy 仕様、および Chromium のセキュリティ設計ドキュメントをご確認ください。
