用語辞典10分で読める

CORSとは — 仕組みと、設定ミス(CORS misconfiguration)で起きること

CORS(オリジン間リソース共有)は、別オリジンのAPI応答をJavaScriptが読めるかをブラウザが制御する仕組みです。設定ミスで第三者サイトにログイン済みのデータを読まれる理由と、安全な設定を解説します。

本文を読む
公開日
更新日
目次

APIに Access-Control-Allow-Origin を付けたら動いた、というだけでは安全とは限りません。CORSは付ければ済むものではなく、許可する相手を絞ることが大切です。仕組みと安全な設定を解説します(攻撃手順は載せません)。

まず仕組み

ブラウザには「別オリジンのJSは勝手に他サイトの応答を読めない」という同一オリジンポリシーがあります。CORSは、その例外をサーバーが明示的に許可した相手にだけ開くためのものです。

オリジンは「スキーム(https)+ホスト名+ポート番号」の組です。https://example.com と https://api.example.com はホスト名が違うので別オリジン、http://example.com と https://example.com もスキームが違うので別オリジンです。

応答ヘッダ意味
Access-Control-Allow-Originどのオリジンに応答の読み取りを許すか
Access-Control-Allow-CredentialsCookie等の認証情報を伴う通信を許すか
Access-Control-Allow-Methods / -Headers許可するHTTPメソッド/ヘッダ

ポイントは、CORSは「制限を緩める」側の仕組みだということ。緩め方を間違えると、本来読めないはずのデータが第三者に読めてしまいます。

もう1つ大事なのは、CORSが止めるのは「応答をJavaScriptが読むこと」だという点です。単純なリクエストはCORSの許可がなくてもサーバーに届き、処理されます。独自ヘッダを付けるなどの場合は、ブラウザが先にOPTIONSメソッドで確認(プリフライト)し、許可されなければ本番のリクエストを送りません。

似た仕組みとの違い

CORSは名前の似た仕組みや、関係の深い脆弱性と混同されがちです。

用語何を決めるか誰が守るか
同一オリジンポリシー別オリジンの応答を読ませない(ブラウザの既定)ブラウザ
CORS同一オリジンポリシーの例外として、読ませる相手を決めるサーバーが宣言し、ブラウザが守る
CSRF利用者のログイン状態で、意図しないリクエストを送らせる攻撃CSRFトークン、SameSite属性で防ぐ
CSP自分のページが読み込んでよいスクリプトや接続先を決めるサーバーが宣言し、ブラウザが守る

CORSは「応答を読めるか」、CSRFは「リクエストを送らせられるか」の問題です。CORSを厳しくしてもCSRFは防げません。

何が危ない設定か

危険な設定(やりがち)

  • リクエストの Origin をそのまま反射して許可する
  • Access-Control-Allow-Origin: * + 認証情報も許可
  • 必要のないAPIまで広く別オリジンに開放

安全な設定

  • 許可リスト(信頼できる固定のオリジンだけ)
  • それ以外は既定で拒否
  • 認証情報を伴うなら * を使わず具体的なオリジンを指定
攻撃者サイトのJSが、あなたのAPIへリクエスト(利用者はログイン中)
↓ サーバーがOriginを鵜呑みに許可(設定ミス)
ブラウザが応答の読み取りを許す=個人情報/トークンが攻撃者サイトに渡る
緩い設定だと、攻撃者サイトのJSが利用者のログイン状態を使ってAPIの応答を読めてしまう。

設定ミスが生まれる典型的な流れ

多くの設定ミスは、CORSエラーを消そうとして起きます。よくある流れは次のとおりです。

  1. フロントエンドからCookie付きでAPIを呼ぶと、CORSエラーになる
  2. Access-Control-Allow-Origin: * を付ける。しかし認証情報を伴う通信では、ブラウザは * の応答を読ませないので、エラーは消えない
  3. 受け取った Origin をそのまま返す設定に変えると、エラーが消える。同時に、どのサイトからでもログイン済みの応答を読める状態になる

許可リストを作っても、照合の仕方を誤ると同じことが起きます。

  • 「example.com で終わる」で照合すると、evil-example.com のような別のドメインも通る
  • 「https://example.com で始まる」で照合すると、https://example.com.evil.net も通る
  • 開発の都合で null オリジンを許可すると、別のサイトが作り出せる null からの読み取りも許してしまう

照合は、オリジン全体(スキーム・ホスト・ポート)の完全一致で行います。

安全な設定の基本

1

許可リスト方式にする(最重要)

あらかじめ決めた信頼できるオリジンだけを許可し、それ以外は拒否(既定で拒否)。「とりあえず全部許可」をしない。
2

Originを鵜呑みに反射しない

リクエストの Origin をそのまま Access-Control-Allow-Origin に echo しない。許可リストと突き合わせて一致したときだけ返す。返す値がリクエストごとに変わるので、Vary: Origin も付けてキャッシュの取り違えを防ぐ。
3

認証情報を伴うなら * を使わない

Cookie等を伴う通信で Access-Control-Allow-Origin: * と Allow-Credentials: true を併用しない。具体的なオリジンを指定する。
4

開く範囲を最小に

別オリジンに公開する必要があるエンドポイントだけを対象にする。広く開けない。* で開けるのは、ログイン不要の公開データだけにする。

自分のサイトで確認する方法

自分のAPIに、別のオリジンを名乗るリクエストを送り、応答ヘッダを見ます。自分が管理するAPIにだけ行います。

# 許可していないオリジンを名乗って、応答ヘッダだけを見る
curl -s -o /dev/null -D - -H "Origin: https://example.com" https://あなたのAPI/ | grep -i "^access-control"
  • Access-Control-Allow-Origin: https://example.com が返ったら、Originを反射している。許可リストの照合を入れる
  • Access-Control-Allow-Origin: * と Access-Control-Allow-Credentials: true が両方あったら、設定を見直す
  • 何も返らないか、自分のフロントエンドのオリジンだけが返るなら問題ない

同じ確認を Origin: null でも行います。所有を確認したサイトなら、サイト総合セキュリティ診断でもOriginの反射と認証情報の許可をまとめて点検できます。ほかのセキュリティヘッダはセキュリティヘッダ診断で確認できます。

当サイトの視点:CORSは『守り』ではなく『緩め方』。緩める相手を絞る

よくある誤解は「CORSヘッダを付ければ安全になる」です。逆で、CORSはブラウザの制限を“緩める”側の仕組み。だから安全のコツは「どう付けるか」より「誰に・どこまで開けるかを最小に絞る」ことです。当サイトは、外部から読めてよいデータと、そうでないデータを分け、既定で拒否・許可リストで例外だけ開ける方針を勧めています。なお、応答を読まれる前提が崩れる XSS や、状態変更を狙う CSRF は別の脆弱性なので、CORSだけで全部が守れるわけではありません。

出典(一次情報)

  • MDN Web Docs「オリジン間リソース共有(CORS)」 — developer.mozilla.org(認証情報付きリクエストでは * を使えない、プリフライトの条件、Vary: Origin)
  • WHATWG Fetch Standard「CORS protocol」 — fetch.spec.whatwg.org
  • OWASP HTML5 Security Cheat Sheet — cheatsheetseries.owasp.org(信頼するドメインだけを許可し、Originをそのまま返さない)
  • PortSwigger Web Security Academy「Cross-origin resource sharing (CORS)」 — portswigger.net(許可リストの照合ミス、null オリジン、CORSはCSRF対策ではない)
  • MITRE CWE-942: Permissive Cross-domain Policy with Untrusted Domains — cwe.mitre.org

次に読む

分類番号

CWE は脆弱性の原因となる弱点の種類を、MITRE ATT&CK は攻撃者の手口を分類した番号体系です。どちらも MITRE が管理し、脆弱性情報や検知ルールの分類に広く使われています。

CWE™: Copyright © 2006–2026, The MITRE Corporation. CWE is a trademark of The MITRE Corporation. The MITRE Corporation hereby grants you a non-exclusive, royalty-free license to use CWE for research, development, and commercial purposes. Any copy you make for such purposes is authorized on the condition that you reproduce MITRE’s copyright designation and this license in any such copy. CWE Terms of Use

よくある質問

QCORSは何のための仕組みですか?
A

ブラウザには『別のオリジン(サイト)のJavaScriptは、勝手に他サイトの応答を読めない』という同一オリジンポリシーがあります。CORS(Cross-Origin Resource Sharing)は、その例外を“サーバーが明示的に許可した相手にだけ”開くための仕組みです。Access-Control-Allow-Origin などの応答ヘッダで、どのオリジンに応答の読み取りを許すかを宣言します。

QCORSの設定ミスで何が起きますか?
A

許可を緩くしすぎると、攻撃者のサイトのJavaScriptから、利用者のログイン済みAPIの応答を読まれる恐れがあります。典型例は、リクエストのOriginをそのまま反射して許可する設定や、Access-Control-Allow-Origin を * にしつつ認証情報(Cookie等)も許可してしまう設定です。結果として個人情報やトークンが第三者サイトに渡り得ます。

Q安全な設定の基本は?
A

『許可リスト方式』です。あらかじめ決めた信頼できるオリジンだけを許可し、それ以外は拒否(既定で拒否)。リクエストのOriginを鵜呑みに反射しない。認証情報を伴う通信では Access-Control-Allow-Origin に * を使わず、具体的なオリジンを指定する。そもそも別オリジンに公開する必要があるエンドポイントだけを対象にする、のが基本です。

QCORSエラーが出たら Access-Control-Allow-Origin を * にすればいい?
A

ログイン不要の公開データだけを返すAPIなら * で問題ありません。ただし、Cookieなどの認証情報を伴う通信では、ブラウザが * の応答を読ませないため、エラーは消えません。そこで受け取ったOriginをそのまま返す設定に変えると、どのサイトからでも読める状態になります。自分のフロントエンドのオリジンを許可リストに書き、一致したときだけ返すのが正しい直し方です。

QCORSを設定すればCSRFは防げますか?
A

防げません。CORSは応答を読めるかを制御する仕組みで、リクエストそのものが送られるかどうかは別です。単純なリクエスト(フォーム送信と同じ形のPOSTなど)は、CORSの許可がなくてもサーバーに届きます。CSRFはCSRFトークンやCookieのSameSite属性で防ぎます。

Qプリフライトリクエストとは?
A

ブラウザが本番のリクエストを送る前に、OPTIONSメソッドで『このメソッドやヘッダで送ってよいか』をサーバーに確認する通信です。独自のヘッダを付ける場合や、application/json のPOST、PUT・DELETEなどで発生します。許可されなければ本番のリクエストは送られません。GET・HEAD・POSTで、決められたヘッダと形式だけを使う単純なリクエストでは発生しません。