CORS (Cross-Origin Resource Sharing)とは
概要
CORS (Cross-Origin Resource Sharing) は、Web ブラウザが異なるオリジン (プロトコル + ドメイン + ポートの組み合わせ) へのリクエストを制御するセキュリティ機構である。ブラウザはデフォルトで同一オリジンポリシー (Same-Origin Policy) を適用し、異なるオリジンへの JavaScript からのリクエストをブロックする。CORS は、サーバーが明示的に許可したオリジンからのリクエストだけを通過させる仕組みを提供する。
同一オリジンポリシーが必要な理由
同一オリジンポリシーがなければ、悪意のある Web サイトがユーザーのブラウザを経由して、ログイン済みの銀行サイトや SNS に勝手にリクエストを送信できてしまう。ブラウザは Cookie を自動的に付与するため、攻撃者のサイトから送られたリクエストでも、ユーザーの認証情報が含まれた状態でサーバーに到達する。
この攻撃は CSRF (Cross-Site Request Forgery) と呼ばれ、同一オリジンポリシーはその根本的な防御策である。CORS はこのポリシーを維持しつつ、正当な異なるオリジン間の通信を可能にする「例外の仕組み」として設計されている。
プリフライトリクエストの仕組み
単純なリクエスト (GET、HEAD、特定の Content-Type を持つ POST) 以外の異なるオリジンへのリクエストでは、ブラウザが本番のリクエストの前に OPTIONS メソッドで「プリフライトリクエスト」を送信する。サーバーは `Access-Control-Allow-Origin`、`Access-Control-Allow-Methods`、`Access-Control-Allow-Headers` などのヘッダーで、許可するオリジン、メソッド、ヘッダーを応答する。
ブラウザはプリフライトの応答を確認し、許可されている場合にのみ本番のリクエストを送信する。この二段階の仕組みにより、サーバーは実際のリクエストを処理する前に、そのリクエストを受け入れるかどうかを判断できる。
質問箱サービスでの CORS 設計
質問箱サービスでは、フロントエンド (Next.js) とバックエンド API (Lambda Function URL) が異なるオリジンで動作する場合に CORS の設定が必要になる。CloudFront を使って同一ドメインの異なるパスにフロントエンドと API を配置する構成では、オリジンが同一になるため CORS の問題は発生しない。
この「同一オリジン構成」は CORS の複雑さを回避する設計上の工夫である。`/api/*` パスを API に、それ以外をフロントエンドにルーティングすることで、ブラウザから見ればすべて同じオリジンへのリクエストになる。CORS ヘッダーの設定ミスによるセキュリティホールや、プリフライトリクエストによるレイテンシ増加を根本的に排除できる。
Web API のセキュリティや設計を学びたい方は、Web API 設計の関連書籍も参考になります。