Web セキュリティ

CORS (オリジン間リソース共有)

約 4 分で読めます

CORS (クロスオリジンリソース共有) とは

CORS (Cross-Origin Resource Sharing) とは、Web ブラウザの同一オリジンポリシーを安全に緩和し、異なるオリジン間でのリソース共有を可能にする HTTP ヘッダーベースの仕組みです。オリジンとは、スキーム (http/https)、ホスト名、ポート番号の 3 つの組み合わせで定義されます。

同一オリジンポリシーは、あるオリジンから読み込まれたスクリプトが別のオリジンのリソースにアクセスすることを制限するブラウザのセキュリティ機構です。この制限がなければ、悪意のあるサイトがユーザーのブラウザを経由して、ログイン中の銀行サイトの API を呼び出すといった攻撃が可能になります。

しかし、現代の Web アプリケーションでは、フロントエンドとバックエンド API が異なるドメインで運用されるケースが一般的です。CORS は、サーバーが「どのオリジンからのアクセスを許可するか」を HTTP レスポンスヘッダーで明示することで、必要なクロスオリジン通信を安全に実現します。

CORS の動作メカニズム

CORS は、リクエストの種類に応じて 2 つの方式で動作します。

単純リクエスト (Simple Request)

GET、HEAD、POST (特定の Content-Type に限る) で、カスタムヘッダーを含まないリクエストは「単純リクエスト」として扱われます。ブラウザはリクエストをそのまま送信し、レスポンスの Access-Control-Allow-Origin ヘッダーを確認します。許可されたオリジンであればレスポンスを JavaScript に渡し、そうでなければブロックします。

プリフライトリクエスト (Preflight Request)

PUT、DELETE、カスタムヘッダーを含むリクエストなど、単純リクエストの条件を満たさない場合、ブラウザは本来のリクエストの前に OPTIONS メソッドで「プリフライトリクエスト」を送信します。サーバーは以下のヘッダーで許可条件を応答します。

  • Access-Control-Allow-Origin: 許可するオリジン
  • Access-Control-Allow-Methods: 許可する HTTP メソッド
  • Access-Control-Allow-Headers: 許可するリクエストヘッダー
  • Access-Control-Max-Age: プリフライト結果のキャッシュ時間 (秒)

プリフライトの応答が許可条件を満たしていれば、ブラウザは本来のリクエストを送信します。

認証情報を含むリクエスト

Cookie や認証ヘッダーを含むクロスオリジンリクエストでは、Access-Control-Allow-Credentials: true が必要です。この場合、Access-Control-Allow-Origin にワイルドカード (*) は使用できず、具体的なオリジンを指定する必要があります。

よくある設定ミスとセキュリティリスク

CORS の設定ミスは、同一オリジンポリシーによる保護を無効化し、深刻なセキュリティリスクを生みます。

  • Access-Control-Allow-Origin: * の安易な使用: すべてのオリジンを許可すると、任意のサイトから API にアクセス可能になる。公開 API 以外では使用すべきでない。特に認証情報を扱う API では絶対に使用してはならない
  • Origin ヘッダーの無検証な反映: リクエストの Origin ヘッダーの値をそのまま Access-Control-Allow-Origin に反映する実装は、実質的にワイルドカードと同じ。ホワイトリストで検証すべき
  • null オリジンの許可: Access-Control-Allow-Origin: null を許可すると、サンドボックス化された iframe やローカルファイルからのアクセスが可能になり、攻撃に悪用される
  • サブドメインの過剰な許可: *.example.com のようなパターンマッチで許可する場合、攻撃者がサブドメインを乗っ取れば CORS を悪用できる

CORS の設定ミスは XSSCSRF と組み合わされることで、被害が拡大する可能性があります。

安全な CORS 設定のベストプラクティス

CORS を安全に設定するための指針を示します。

  • 許可するオリジンをホワイトリストで管理する: 環境変数や設定ファイルで許可オリジンのリストを管理し、リクエストの Origin ヘッダーと完全一致で検証する
  • 必要最小限のメソッドとヘッダーを許可する: Access-Control-Allow-MethodsAccess-Control-Allow-Headers には、実際に使用するものだけを列挙する
  • プリフライトのキャッシュを活用する: Access-Control-Max-Age を適切に設定し、プリフライトリクエストの頻度を減らしてパフォーマンスを改善する
  • 認証情報を含むリクエストは慎重に扱う: Access-Control-Allow-Credentials: true を設定する場合、許可オリジンを厳密に制限する
  • CSPセキュリティヘッダーと併用する: CORS 単独ではなく、他のセキュリティヘッダーと組み合わせて多層防御を構築する
  • HTTPS を前提とする: HTTP オリジンを許可リストに含めない。中間者攻撃によるオリジンの偽装を防ぐ

CORS はブラウザ側の制御であり、サーバー間通信やコマンドラインツールからのリクエストには適用されません。CORS だけに依存せず、サーバー側の認証・認可を必ず実装してください。

よくある誤解

CORS はサーバーを保護するセキュリティ機能
CORS はブラウザ側の制御であり、サーバーを直接保護するものではない。curl やサーバー間通信では CORS の制限は適用されない。CORS はブラウザのユーザーを保護する仕組みであり、サーバー側の認証・認可とは別のレイヤーの対策。
CORS エラーが出たらワイルドカード (*) で解決すればよい
ワイルドカードはすべてのオリジンからのアクセスを許可するため、セキュリティリスクが高い。認証情報を含むリクエストでは使用できない。正しい対処は、必要なオリジンだけをホワイトリストに追加すること。

関連用語

関連記事