Overview
CORS(Cross-Origin Resource Sharing:クロスオリジンリソース共有)とは、Webブラウザが異なるオリジン(ドメイン・プロトコル・ポートの組み合わせ)間でのリソース共有を安全に制御するための仕組みです。ブラウザに実装された同一オリジンポリシー(Same-Origin Policy)を緩和し、信頼されたオリジンからのクロスオリジンリクエストのみを許可します。
CORSは、サーバーが特定のHTTPレスポンスヘッダー(Access-Control-Allow-Originなど)を返すことで機能します。ブラウザはリクエスト先のオリジンとレスポンスヘッダーの値を比較し、許可されていればレスポンスデータへのアクセスを許可し、許可されていなければブロックします。これにより、悪意のあるWebサイトが別のサイトのAPIから勝手にデータを取得することを防ぎます。
特に注意が必要なのがプリフライトリクエスト(Preflight Request)です。PUT/DELETE等のメソッドやカスタムヘッダーを含むリクエストでは、ブラウザが事前にOPTIONSメソッドで問い合わせを行い、サーバーがそのリクエストを許可するかを確認します。CORS設定の不備は、情報漏洩やCSRF攻撃の温床となるため、正確な設定が不可欠です。
Details
同一オリジンポリシー(Same-Origin Policy)
同一オリジンポリシーは、Webセキュリティの最も基本的な防御機構です。オリジンとは「プロトコル+ホスト名+ポート番号」の組み合わせで定義され、異なるオリジン間ではDOM操作、Cookie、XMLHttpRequest/Fetchによるデータ読み取りが制限されます。例えば、https://example.comのページからは、https://api.other.comのAPIレスポンスを直接読み取ることはできません。
この制約がなければ、悪意のあるサイトがユーザーのブラウザを介して銀行サイトのAPIにリクエストを送り、残高情報などを窃取することが可能になってしまいます。CORSはこの厳格なポリシーに対して、安全な例外を設けるための標準規格です。
CORSヘッダーの種類と役割
- Access-Control-Allow-Origin:アクセスを許可するオリジンを指定。特定のオリジン(例:https://app.example.com)またはワイルドカード(*)を設定可能
- Access-Control-Allow-Methods:許可するHTTPメソッド(GET, POST, PUT, DELETEなど)を指定
- Access-Control-Allow-Headers:リクエストで使用可能なカスタムヘッダーを指定(Authorization, Content-Typeなど)
- Access-Control-Allow-Credentials:Cookieや認証情報を含むリクエストを許可するかどうかをtrue/falseで指定
- Access-Control-Max-Age:プリフライトリクエストの結果をキャッシュする秒数を指定
- Access-Control-Expose-Headers:JavaScriptからアクセス可能なレスポンスヘッダーを指定
プリフライトリクエスト(OPTIONS)
ブラウザは「単純リクエスト」以外のクロスオリジンリクエストを送信する前に、OPTIONSメソッドによるプリフライトリクエストを自動的に送信します。単純リクエストとは、GET/HEAD/POSTメソッドで、かつ標準的なヘッダーのみを使用するリクエストです。
プリフライトリクエストにより、サーバーは実際のリクエストが送信される前に、そのリクエストを許可するかどうかを判断できます。サーバーがOPTIONSリクエストに対して適切なCORSヘッダーを返さなければ、ブラウザは本来のリクエストを送信しません。
クレデンシャル付きリクエスト
CookieやHTTP認証情報を含むクロスオリジンリクエストを送信するには、クライアント側でcredentials: 'include'(Fetch API)またはwithCredentials: true(XMLHttpRequest)を設定し、サーバー側でAccess-Control-Allow-Credentials: trueを返す必要があります。
重要な制約として、クレデンシャル付きリクエストではAccess-Control-Allow-Originにワイルドカード(*)は使用できません。必ず具体的なオリジンを指定する必要があります。この制約はセキュリティ上極めて重要であり、違反するとブラウザがレスポンスをブロックします。
ワイルドカード(*)の制限と注意点
Access-Control-Allow-Origin: *は、すべてのオリジンからのアクセスを許可する設定です。公開APIやCDNのような認証不要のリソースでは適切ですが、機密データを扱うAPIでは絶対に使用してはなりません。
また、ワイルドカードを使用する場合、Access-Control-Allow-Credentialsをtrueに設定することはできません。一部の開発者がこの制約を回避するために、リクエストのOriginヘッダーの値をそのままAccess-Control-Allow-Originに反映する実装(オリジンリフレクション)を行いますが、これは極めて危険な設定であり、事実上すべてのオリジンにクレデンシャル付きアクセスを許可してしまいます。
CORS設定ミスの危険性
CORSの設定ミスは深刻なセキュリティリスクをもたらします。代表的な危険な設定として、Originヘッダーの値を無検証で反映するオリジンリフレクション、nullオリジンの許可(サンドボックス化されたiframeから悪用可能)、正規表現による不完全なオリジン検証(例:example.comを検証する際にevil-example.comも通過してしまう)などがあります。
これらの設定ミスにより、攻撃者は被害者のブラウザを介してAPIから機密データを窃取したり、認証済みセッションを悪用してデータを改ざんしたりすることが可能になります。
Security Measures
- 01許可するオリジンを明示的にホワイトリスト化:Access-Control-Allow-Originにワイルドカード(*)を安易に使用せず、信頼するオリジンのみをホワイトリストで管理してください。動的にオリジンを検証する場合も、完全一致で比較し、部分一致や正規表現の不備による意図しないオリジンの許可を防ぎましょう。
- 02クレデンシャル付きリクエストの厳格な管理:Access-Control-Allow-Credentials: trueを設定する場合は、必ず具体的なオリジンを指定し、ワイルドカードとの併用を避けてください。Originヘッダーの値をそのまま反映するオリジンリフレクションは絶対に行わないでください。
- 03nullオリジンを許可しない:Access-Control-Allow-Origin: nullは、サンドボックス化されたiframeやローカルファイルからのリクエストに使用されますが、攻撃者が悪用可能なため、本番環境では許可しないでください。
- 04プリフライトリクエストのキャッシュ設定:Access-Control-Max-Ageを適切に設定し、プリフライトリクエストの頻度を削減してパフォーマンスを改善しつつ、キャッシュ期間を長くしすぎないことでセキュリティポリシーの変更を適時反映させましょう。
- 05不要なHTTPメソッドとヘッダーの制限:Access-Control-Allow-MethodsとAccess-Control-Allow-Headersには、実際に必要なメソッドとヘッダーのみを列挙してください。過剰に許可すると攻撃対象面が拡大します。
- 06CORS設定の定期的な監査とテスト:curl等のツールやセキュリティスキャナーを使用して、CORS設定が意図通りに動作しているか定期的にテストしてください。特にOriginヘッダーに任意の値を設定したリクエストを送信し、不正なオリジンが許可されないことを確認しましょう。
Incidents
📋 Slack CORS脆弱性によるトークン窃取(2017年)
2017年、セキュリティ研究者がSlackのCORS設定に脆弱性を発見しました。SlackのAPIが特定の条件下でオリジン検証を適切に行っておらず、攻撃者が悪意のあるWebページを通じて、Slackにログイン中のユーザーのセッショントークンやワークスペース情報にアクセスできる状態でした。
この脆弱性を悪用すると、攻撃者はユーザーが閲覧するだけで、そのユーザーのSlackアカウントに紐づく認証トークンを窃取し、プライベートチャンネルのメッセージやファイルにアクセスすることが可能でした。Slackはバグバウンティプログラムを通じて報告を受け、速やかにCORS設定を修正しました。
📋 BitBucket CORS設定ミスによるプライベートリポジトリ漏洩(2018年)
2018年、AtlassianのBitBucketにおいてCORS設定の不備が発見されました。APIエンドポイントがOriginヘッダーの値を無検証で反映するオリジンリフレクションの状態にあり、任意のオリジンからクレデンシャル付きリクエストを送信できる状態でした。
この脆弱性により、攻撃者は悪意のあるWebサイトを閲覧したBitBucketユーザーのプライベートリポジトリのソースコードを窃取できる可能性がありました。企業の機密コードやAPIキーなどの秘密情報が漏洩するリスクがあり、Atlassianは発見後にCORS設定を厳格化し、許可するオリジンのホワイトリスト制に移行しました。
📋 大手ECサイトにおけるCORS設定ミスによる顧客データ漏洩
複数の大手ECサイトにおいて、CORSの設定不備が原因で顧客の個人情報が漏洩するリスクが報告されています。典型的なパターンとして、開発環境で設定したAccess-Control-Allow-Origin: *が本番環境にそのまま反映され、ユーザーの注文履歴や住所情報を含むAPIレスポンスが任意のオリジンからアクセス可能になるケースがあります。
また、サブドメインのみを許可する正規表現の不備により、攻撃者が類似ドメインを取得してCORSチェックを通過するケースも報告されています。これらの事例は、開発段階でのセキュリティレビューとCORS設定の自動テストの重要性を浮き彫りにしています。