見えるセキュリティ

同一オリジンポリシー(SOP)

SAME-ORIGIN POLICY

この概念とは?

同一オリジンポリシー(SOP)は、あるページのJavaScriptが、別オリジンの情報にアクセスする方法を制限する、ブラウザの基本ルールです。悪意のあるページが、ほかのページの中身を勝手に読み取ることなどを防ぎます。ここでは、ページ内に埋め込んだ注文ページの中身を読めるか、比較します。

ページが表示されることと、JavaScriptがその中身を読めることは別です。

THEME
web-vuln
KIND
mechanism
REVIEW
self-reviewed ·

オリジンとは?

通常のHTTP(S)のURLでは、「スキーム・ホスト・ポート」の組み合わせがオリジンを決めます。[S01][S02]

URLを分けて見る

https://app.example:443/dashboard

スキーム
https
ホスト
app.example
ポート
443

/dashboard はパスで、オリジンに含まれません。

HTTPSの標準ポートは443です。:443を省略しても同じオリジンです。[S02]

表示済みの注文ページから、外側のJavaScriptが注文番号を読み取れるか

両モードともSOPは有効です。注文ページは固定し、外側のページのホストだけを変えます。

この例では、注文ページを両方の条件で表示できます。比較するのは、外側のJavaScriptが注文番号を直接読めるかです。

ブラウザSOPは有効

外側のページ

https://other.example/dashboard

外側のJavaScript

まだ読み取っていません

ブラウザ内部の確認

DOMを読むときにオリジンを確認

iframe · 注文ページ

ページ内に別のページを表示する枠

https://app.example/orders

注文内容

注文番号
A-1042
商品
ノート

どちらの条件でも表示済み

外側のJavaScriptが取得した値

まだ読み取っていません

表示は概念図です。実際のiframeや通信、コードの実行は行いません。

この比較の前提と対応する操作
  • 通常のHTTPSページが読み込みを完了した後の状態を扱います。
  • 注文ページのiframe埋め込みをX-Frame-Options等の設定が妨げていないものとします。その他の読み込み制限も、この比較では発生していません。[S08]
  • iframeのsandboxによるオリジンの変更や、特殊なURLによるopaque originは扱いません。
  • document.domainによる従来の緩和は使わず、有効化・推奨しません。[S01]
  • 両モードともSOPは有効です。モード切替はブラウザ保護のON/OFFではありません。
  • 認証、Cookie送信、サーバーのアクセス制御、ページの取得過程は比較対象から外します。表示済みの架空データを使い、SOPがサーバー側の認証・認可を代替するという意味ではありません。
  • 外側のページが自身のiframeを通じて参照を持っている場面です。無関係なタブをJavaScriptが自由に探せるという意味ではありません。
  • 各STEPは理解のための分解です。1回のDOMアクセスが4回のHTTP通信や4回の非同期処理になるわけではありません。

読み込み済みのiframeをframeで参照し、注文ページにid="order-id"の要素がある例です。

const orderId = frame.contentWindow.document
  .getElementById("order-id").textContent;

同一オリジンではA-1042を取得します。別オリジンではcontentWindow.documentへのアクセスが拒否され、SecurityErrorになります。異なるAPIやすべてのSOP違反が同じエラーになる、という意味ではありません。[S03][S04]

対応を説明するコードであり、教材では実行しません。

STEP 01 / 4

注文ページは表示されている

STEP 1 / 4: 注文ページは表示されている

現在のSTEP 1STEP 2STEP 3STEP 4

外側のページに、注文ページを埋め込んでいます。画面には注文番号が表示されています。

技術的な詳細を見る

埋め込みの表示とDOMへの直接アクセスは別の操作です。本例では通常のHTTPSページが読み込みを完了し、iframeの埋め込みを妨げる条件を除いています。[S04][S08]

パネルの開閉ではSTEPは変わりません。

この概念の要点

  • 要点

    オリジンはURLの3要素で比べる。

    通常のHTTP(S)ではスキーム・ホスト・ポートで判定し、パスは含めません。[S01][S02]

  • 要点

    表示と読み取りは別。

    別オリジンのページが表示されても、外側のJavaScriptがそのDOMを直接読めるとは限りません。[S03][S04]

  • 要点

    制限する操作を区別する。

    DOMの直接読み取り、API応答の読み取り、ページの埋め込みは、それぞれのルールを確認します。[S03][S05][S08][S09]

理解確認

基準URLはhttps://app.example/dashboardです。同一オリジンなのはどれでしょう?

理解確認

別オリジンの注文ページがiframe内に表示されています。本編の条件で、外側のJavaScriptが注文番号を直接読もうとすると、どうなるでしょう?

理解確認

注文ページのHTTP応答にCORSの許可を付ければ、別オリジンの外側のJavaScriptが、そのiframeのDOMを直接読めるようになるでしょうか?

SOPの補足

オリジンを比べてみる

基準URL:https://app.example/dashboard

比較するURL:https://app.example/orders
オリジンの3要素を比較
ページスキームホストポート
基準URLhttpsapp.example443
比較URLhttpsapp.example443
比較一致一致一致

パス(オリジンに含まれません)

基準URL:/dashboard

比較URL:/orders

同一オリジン。パスは判定に含まれません。

URLの比較例であり通信は行いません。通常のHTTP(S)の固定例だけを扱います。

ポートを省略した場合は、HTTPSなら443、HTTPなら80として比較します。[S02]

別オリジンと情報を共有したいとき
API応答を読む:CORS
  1. 1APIの応答
  2. 2ブラウザの許可確認
  3. 3ページのJavaScript

API応答をJavaScriptへ公開する条件は、CORSで伝えます。[S05]

ページ同士で渡す:postMessage
  1. 1注文ページのJavaScript
  2. 2渡すと決めたデータ
  3. 3外側のJavaScript

ページ同士が協力して、必要なデータをメッセージとして渡せます。[S06]

postMessageでは、送信先のオリジンを指定し、受信側でも送信元のオリジンとデータを確認します。必要に応じて送信元のウィンドウも照合します。直接のDOM読み取りを許す設定ではありません。[S06][S07]

CORSの仕組みを学ぶ
ページの表示自体を制限するには?
本編:表示と読み取りは別

外側のページ(別オリジン)

注文ページ:表示できる

注文番号 A-1042・商品 ノート

外側のJSは読めない

別の制御:埋め込みを制限する

埋め込みを制限する設定

iframeへの表示を拒否

ページをiframeへ埋め込めるかどうかは、別の制御です。例えばX-Frame-Optionsは、iframeなどへの表示を制限するために使います。[S08]

参考資料

RELATED CONCEPTS