1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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

Last updated at Posted at 2025-12-04

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

同一オリジンポリシー(SOP) とは、ブラウザ上で動作するスクリプトは、自身と同じオリジンを持つリソースに対してのみ自由にアクセスできる、という制約を課すセキュリティモデルです。

ここでいうオリジンは、次の3要素の組み合わせです。

  • スキーム(プロトコル): http, https
  • ホスト: example.com, api.example.com
  • ポート: 80, 443, 8080 など

したがって、オリジン = scheme://host:port となります。

具体例として、次のように判断されます。

  • https://example.comhttps://example.com:443
    → スキームが https の場合、ポート 443 はデフォルトポートとして扱われるため 同一オリジン (http の場合はポート 80 がデフォルト)
  • https://example.comhttp://example.com
    → スキームが異なるため 別オリジン
  • https://example.comhttps://api.example.com
    → ホストが異なるため 別オリジン
  • https://example.com:443https://example.com:8443
    → ポートが異なるため 別オリジン

SOPが必要とされる背景

SOPが必要な理由は、ブラウザはユーザのCookieやログイン状態といった機密度の高い情報を保持しているためです。

仮にSOPが存在しなかった場合、XSSやCSRFなどの攻撃が極めて容易になってしまいます。

SOPが影響する範囲

SOPが影響するのは次のような場面です。

  • DOM や document へのアクセス(別オリジンの iframe など)
  • fetch などによるHTTPレスポンスの読み取り

いずれの場合も、「通信そのもの」ではなく、結果をスクリプトから読み取れるかどうかが制御されます。

代表的な具体例として、次のようなケースがあります。

  • フロントエンドのSPA(例: https://frontend.example.com)から、別オリジンのAPI(例: https://api.other.com)へ fetch でリクエストを送る場合、
    • リクエスト自体は送信されるものの、サーバ側で適切なCORS設定が行われていなければ、レスポンスボディをJavaScriptから参照することはできない
  • サイトA(例: https://app.example.com)が、別オリジンのサイトB(例: YouTube)の iframe を埋め込む場合、
    • 見た目としては同じページ内に表示されるが、サイトAのスクリプトから、iframe 内の document を直接読み書きすることはできない

同一オリジンと別オリジンの挙動の違い

厳密には例外も多く存在しますが、おおまかに整理すると次のようになります。

対象 同一オリジン 別オリジン(SOP適用時)
DOMアクセス(document など) 読み書き可能 原則不可(別オリジン iframe の中身など)
fetch 等のレスポンス読み取り 本文をスクリプトから参照可能 原則不可(CORSで許可された場合のみ参照可能)
localStorage / sessionStorage 当該オリジンのデータにアクセス可能 別オリジンのストレージにはアクセス不可
Cookie JSから参照可能(HttpOnly でなければ) リクエスト自体には自動で含めて送信されるが、JSから別オリジンのCookieは参照不可
window.opener / window.parent アクセス可能(セキュリティには注意) 制約あり(同一オリジンでない場合は操作が制限される)

CORSとは

CORS(Cross-Origin Resource Sharing) とは、あるオリジン上で動作しているWebアプリケーションが、別のオリジンにあるリソースへ安全にアクセスできるようにするための仕組みです。

SOPによって本来はブロックされるクロスオリジンのレスポンス参照を、サーバ側の明示的な許可にもとづいて例外的に認めるためのプロトコルという位置付けになります。

CORSの基本的な考え方

ブラウザは、別オリジンへのリクエスト自体は送信するが、レスポンスをJavaScriptから参照してよいかどうかは、レスポンスヘッダでサーバが宣言した内容に従って判断するというのがCORSの基本的な考え方です。

このときサーバは、次のようなヘッダを用いて許可範囲を指定します。

  • Access-Control-Allow-Origin
    • どのオリジンからのリクエストを許可するか(例: https://frontend.example.com
  • Access-Control-Allow-Credentials
    • Cookie などの資格情報付きリクエストを許可するか
    • true を返す場合、Access-Control-Allow-Origin: * のようなワイルドカード指定は使えず、特定のオリジンを明示する必要がある
  • Access-Control-Allow-Methods
    • 許可するHTTPメソッド(例: GET, POST, OPTIONS
  • Access-Control-Allow-Headers
    • クライアントから送信を許可するリクエストヘッダ

シンプルリクエストとプリフライトリクエスト

ブラウザがCORSを扱う際、すべてのリクエストで一律にプリフライト(事前確認)の OPTIONS リクエストを送信しているわけではありません。挙動は大きく次の2種類に分類されます。

  • シンプルリクエスト
  • プリフライト付きリクエスト

シンプルリクエストとは

次の条件をすべて満たす場合、ブラウザは事前の OPTIONS リクエストを行わず、直接本来のリクエストを送信します。このリクエストはシンプルリクエストと呼ばれます。

  • メソッドが GET / HEAD / POST のいずれかである
  • 送信するヘッダが、ブラウザが自動的に付与する一部の「安全な」ヘッダに限定されている
    • 例: Accept, Accept-Language, Content-Language など
  • Content-Type が次のいずれかである
    • text/plain
    • application/x-www-form-urlencoded
    • multipart/form-data

この場合でもレスポンスボディをJavaScriptから参照できるかどうかの判断はCORSレスポンスヘッダにもとづいて行われます。

プリフライトリクエストとは

上記の条件を満たさないリクエストについては、ブラウザは本来のリクエストを送信する前に、OPTIONS メソッドによる事前確認をサーバに対して行います。この事前確認用のリクエストが プリフライトリクエスト です。

例えば次のようなケースです。

  • PUT / PATCH / DELETE などのメソッドを用いる場合
  • カスタムヘッダ(例: X-Requested-With, X-CSRF-Token などの独自ヘッダ)を付与する場合
  • Content-Type: application/jsonPOST する場合

ブラウザは、プリフライトのレスポンスに含まれる次のヘッダを確認し、本来のリクエストを送信してよいかどうかを判断します。

  • Access-Control-Allow-Methods
  • Access-Control-Allow-Headers
  • Access-Control-Allow-Origin

ここでサーバが適切な値を返さない場合、本来のリクエスト自体が送信されない、あるいは送信されても結果がJavaScriptから参照できないといった挙動になります。

まとめ

  • 同一オリジンポリシー(SOP)は、
    scheme + host + port が同じオリジンの中だけで自由にリソースにアクセスできるというブラウザの基本ルール
  • 別オリジンのリソースに対してはDOMアクセス、レスポンス読み取り、ストレージアクセスなどが制限される特定の相手だけ例外的に許すための仕組み
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?