
CORS(Cross-Origin Resource Sharing)はブラウザがJavaScriptから別オリジンのHTTPリソースへアクセスする際の可否を制御する機構で、W3Cが2014年1月にRecommendationを公開し、現在はFetch Living Standardの一部として維持されている。同一オリジンポリシー(Same-Origin Policy)が課す厳しい遮断を、サーバ側のレスポンスヘッダで明示的に緩和できる仕組みであり、現代のSPAやマイクロサービスを成り立たせる前提条件となっている。本稿では設計思想、プロトコル動作、設定要点、誤用パターンを整理する。
この記事の目次
- 同一オリジンポリシーとCORS登場の背景
- プリフライトとシンプルリクエストの違い
- 実装時に注意する設定とヘッダ
- セキュリティリスクと運用上の落とし穴
- まとめ
同一オリジンポリシーとCORS登場の背景

1995年にNetscape Navigatorに導入された同一オリジンポリシーは、スキーム・ホスト・ポートの三要素が一致する場合のみDOMやXMLHttpRequestを通じたデータ取得を許す仕組みで、長年Webセキュリティの基礎となってきた。しかしAjaxの普及で異なるサーバ上のAPIを呼び出す需要が高まり、JSONPやサーバ側プロキシといった代替策が乱立していた。これらは脆弱性混入のリスクが高く、より洗練された枠組みが求められた。
W3CのWeb Applications Working Groupは2004年からCross-Origin Resource Sharingの仕様策定に着手し、2014年1月16日にRecommendationとして公開した。その後WHATWGがFetch Standardへ統合し、現在はそちらが唯一の更新ソースとなっている。クライアントとサーバが明示的に合意した範囲だけを開放する設計は、JSONPに比べてはるかに安全で柔軟性が高く、OpenAPIやマイクロサービスの普及と相まって事実上の標準となった。
プリフライトとシンプルリクエストの違い

CORSはリクエストを大きく二種類に分類する。シンプルリクエストはGET、HEAD、POSTのいずれかで、ヘッダがAccept、Accept-Language、Content-Languageなど安全な集合に限定され、Content-Typeがapplication/x-www-form-urlencoded、multipart/form-data、text/plainのいずれかである場合に該当する。それ以外、たとえばPUTやDELETE、独自ヘッダを伴うリクエストは「プリフライト」が必須となる。
プリフライトではブラウザが本リクエストの直前にOPTIONSメソッドを送信し、Access-Control-Request-MethodとAccess-Control-Request-Headersでこれから送る内容を申告する。サーバはAccess-Control-Allow-Origin、Allow-Methods、Allow-Headers、Max-Ageなどで許可範囲と結果のキャッシュ時間を返す。認証情報(Cookieやクライアント証明書)を含めたい場合はクライアント側でcredentials: 'include'、サーバ側でAccess-Control-Allow-Credentials: trueの両方が必要であり、この場合Access-Control-Allow-Originにワイルドカードは使えない。
実装時に注意する設定とヘッダ

サーバ側で押さえる主要ヘッダはAccess-Control-Allow-Origin(許可オリジン)、Allow-Credentials(資格情報の可否)、Allow-Methods、Allow-Headers、Expose-Headers(クライアントから読み取れるヘッダ)、Max-Age(プリフライトキャッシュ秒数)である。Allow-Originは動的に組み立てる場合、信頼するドメインリストとの一致を厳密に確認し、リクエストOriginの単純エコーは避ける必要がある。Varyヘッダにオリジンを含めることでキャッシュ汚染も防げる。
実装フレームワークではNode.jsのcorsパッケージ、SpringのCorsConfiguration、Django CORS Headers、ASP.NET Coreの組み込みミドルウェアなど、オリジンとメソッドをホワイトリスト管理する仕組みが用意されている。CDN前段で設定する場合はオリジン応答との二重設定に注意が必要で、Cloudflare、CloudFront、Akamaiは独自のCORS書き換え機能を持つ。誤って同名ヘッダが二重に返ると一部ブラウザはエラー扱いするため、Edgeでの設定とアプリ層の設定はどちらか一方に集約する設計が望ましい。
セキュリティリスクと運用上の落とし穴

CORSはアクセス制御を緩める仕組みである以上、設定ミスは重大な脆弱性に直結する。Allow-Origin: *とAllow-Credentials: trueの組み合わせは規格上禁止されているが、Allow-Originに任意のオリジンを反射するうえCredentialsを許す実装は、被害者ブラウザのCookieつきリクエストを攻撃者ドメインから読み取れるという深刻なリスクを生む。
またCORSはあくまでブラウザの保護機構であり、サーバ側の認可ロジックを置き換えるものではない。CSRF対策にはSameSite=LaxやStrictのCookie属性、二重送信トークンなどを併用する必要があり、APIサーバではOAuth 2.0やJWTの検証で正当性を担保するのが一般的である。プリフライトが多発するとレイテンシが嵩むため、Max-Ageを適切に設定し、フロントとバックでドメインを統一できる場合はリバースプロキシ経由のSame-Origin運用が選ばれる場合もある。
まとめ
CORSは同一オリジンポリシーを安全に緩和するための標準であり、ブラウザとサーバ双方の協調で動作する。プリフライトと認証情報の扱い、ホワイトリスト管理、CDNとの整合という三点を押さえれば、脆弱性を持ち込まずに分散構成のWebアプリを構築できる。
※本記事はIT用語辞典の手書きドラフトです。公開前に最新情報・出典を確認のうえ加筆修正してください。

コメント