한국어 | English | 日本語
Webアプリケーションエンジニア (経験8.8年)
技術・開発
engineering
ウェブフロントエンドと バックエンド開発を扱います

CORS - クロスオリジンAJAX呼び出しのためのSOP補完ポリシー

私がWeb開発を始めたばかりの頃、最初に出くわした問題がCORSでした。CORSはそれ自体が問題ではなく、開発者にそのリクエストがCORS規則に従っていないことを伝えるための規約です。CORS規約はWebブラウザのセキュリティ要素です。ブログを作成する際、外部画像をリンクすることがあります。このように外部にある単純なリソースを取得することはセキュリティ上の問題になりませんが、POSTやPUTのようなAJAX呼び出しを通じて外部にある動的なリソースを取得することは、サーバーの状態を変更するためセキュリティ上の問題となります。したがって、サーバーの状態変更(クッキーヘッダーなどを介したクライアントの状態変更も含む)に関連する呼び出しの際には、その呼び出しが開発者の意図したものかどうかを厳密に検証する必要があります。そうしないと、ブログに悪意のあるスクリプトが注入され、外部ドメインに対して意図しないサーバーリソースを操作するAJAXが呼び出される可能性があるからです。
ウェブブラウザに表示されるすべてのリソースは、同一ドメインから取得されることもありますが、多様なリソース活用のため外部ドメインから取得されることもあります。ドメインが同じ場合はSame Origin、異なる場合はCross Originと表記されます。ブラウザは最低限のセキュリティのために、単純なリソースの取得においてはCross Originも許可するなど、SOP(Same Origin Policy)というポリシーを持っています。AJAX呼び出しは単純なリソースではなく、外部ドメインのリソースを操作する危険性があるため、SOPによってブロックされてしまいます。CORSは、SOPによってブロックされる外部ドメインへのAJAXを可能にする追加ポリシーです。

ブラウザのSOP(Same Origin Policy)ポリシー

ブラウザでのHTTPリクエストは、基本的にSOP(Same Origin Policy)ポリシーに従います。

Same Origin Policyという名称から、SOPポリシーがリソースを呼び出したドメインとリソースを提供するドメインが必ず同一でなければならないと誤解されがちですが、セキュリティ上の問題がない範囲で以下のケースについては例外的に許可されます。ちなみに、Cross-site = Cross-domain = Cross-origin はすべて同じ意味です。

AJAX (Asynchronous JavaScript and XML)

AJAXとは何でしょうか?これは、サーバーと通信する際に使用される非同期JavaScriptをサポートするもので、フロントエンドでデータを取得するためにサーバーを呼び出す際によく使われるaxiosやfetchの根幹となる技術です。現在、ほとんどの主要なウェブブラウザは、サーバーにデータをリクエストするためにXHR(XmlHttpRequest)オブジェクトを内蔵し、非同期処理を行っています。W3C標準ではないため、ブラウザごとに設計方式に違いはありますが、すべてXHRオブジェクトを通じて実装されています。このXHRオブジェクトを通じて、ウェブページがすべてロードされた後でもサーバーにデータをリクエストしたり受け取ったりして、ページの一部だけを更新することができるのです。

CORSの登場 - クロスオリジンAJAX呼び出しのために

AJAXはどのようなサーバーでも呼び出すことができるため、同一ドメインのサーバーから情報を取得することも、異なるドメインから情報を取得することも可能です。開発者の意図に基づいたAJAX呼び出しのみが可能であれば良いのですが、ユーザーに悪意のあるスクリプトを実行させ、他のドメインサーバーに対して悪意のあるAJAX呼び出しを実行させる**CSRF(Cross-site Request Forgery)**という脆弱性があります。

このような脆弱性があるため、SOPポリシーはAJAXをブロックすべきですが、AJAXはW3C標準ではないにもかかわらず、事実上の非同期標準として使用されているため、CORSという例外ポリシーが導入されました。CORSポリシーは、悪意のあるAJAX呼び出しを防ぐために、クライアント(ブラウザ)とサーバー間で、そのAJAX呼び出しが意図されたものであるかどうかを相互に交差検証する仕組みを提供しています。

CORSポリシーさえ遵守すれば、AJAXを介したクロスオリジン呼び出しを許可するというものです。

CORSポリシー検証手順

CORSはブラウザの実装仕様に含まれるHTTP必須ポリシーであり、SOPと同様にCORSポリシーの通過可否はブラウザが判断します。ブラウザはサーバーから応答を受け取りますが、応答分析後にCORS違反であればそのまま破棄します。したがって、ブラウザを介さずにサーバー間で通信を行う際には、このポリシーは適用されません

CORSリクエストの種類

ブラウザはAJAX呼び出しを2種類の組み合わせに分類し、CORSポリシー検証手順を異なる方法で適用しますが、これはドキュメント定義のための区分と見られ、簡単に言えば次のように理解できます。

具体的な学習のために、2種類の組み合わせについて見ていきましょう。

Simple/Preflight Request

AJAXで使用されるHTTPメソッドが、単純な照会に使われるGET、HEADであれば、サーバーを操作できないメソッドであるため、実際のリクエストに対する戻り値を受け取り、それに含まれるヘッダーを通じてCORS検証を行います。しかし、**サーバーの状態を変更するメソッド(POST、PUT、DELETE)**である場合や、カスタムヘッダー(クッキー保存など)が含まれている場合は、実際のリクエストを送信する前に予備リクエスト(Method = OPTIONS)を送り、実際の戻り値なしでヘッダーのみを受け取りCORS検証を行います。CORS検証が完了した後、実際のリクエストを送信してサーバーの状態を変更します。

Simple Request

サーバーを操作できないメソッドであるため、クライアントは実際のリクエストを送信し、(1) 許可されたオリジンの一致のみを確認します。

Preflight Request

サーバーを操作できるメソッドであるため、クライアントは実際のリクエストではなく予備(プリフライト)リクエストを送信し、(1) 許可されたオリジン(2) 許可されたメソッド(3) 許可されたヘッダーのすべての一致を確認します。

Credential (資格情報)

**資格情報(Credential)**とは、Cookie、Authorization Headers、またはTLSクライアント認証を意味します。資格情報(Credential)は、クライアントがXMLHttpRequest.withCredentialsまたはFetch APIのRequest()コンストラクタのcredentialsオプションを通じて「資格情報モード」を有効にしてリクエストすると、サーバーがクライアントに「資格情報ヘッダー」に値を含めて送信します。この時、サーバーは以下の「CORSヘッダー」を通じて、クライアントが「資格情報ヘッダー」の値を見ることができるか否かを同時に送信し、ブラウザはその「CORSヘッダー」がtrueであればクライアントに「資格情報ヘッダー」を公開し、falseまたは存在しない場合(デフォルトはfalse)は「資格情報ヘッダー」をすべて破棄しクライアントから隠します。

注意すべき点は、Credentialリクエストの場合、CORSヘッダーのAccess-Control-Allow-Originの値が*であってはならないことです。a.comのような具体的なドメインが指定されている必要があります。

例で見てみる

Simple Request

a.comドメインからb.comドメインへAJAX呼び出しを行う場合:

Preflight Request

a.comドメインからb.comドメインへAJAX呼び出しを行う場合:

追加のCORS関連HTTPレスポンスヘッダー

Access-Control-Allow-MethodsAccess-Control-Allow-Headersなど、これまで見てきたものとは異なり、サーバーが応答時にさらに送るCORS関連ヘッダーがいくつかあるので、それらを説明して終わりにします。

Access-Control-Max-Age

Preflight Requestの場合、毎回OPTIONS予備リクエストを送受信すると、実際の結果値が返されるまでに時間がかかるため、予備リクエストに対するCORSレスポンスヘッダーの値をブラウザにどのくらいの時間保存できるかをサーバーが指定できます。

Access-Control-Expose-Headers

Access-Control-Allow-HeadersのAllowが、サーバーが**「クライアントがどのヘッダーを送信できるか」を許可するヘッダーであるのに対し、Exposeが付いたこのヘッダーは、「サーバーが送信するヘッダー」の中でブラウザが読み取れるヘッダーを明示**するものです。


  1. HomoEfficio : Cross Origin Resource Sharing - CORS
  2. MDN : Same-Origin Policy
  3. MDN : Cross-Origin Resource Sharing (CORS)
  4. MDN : Access-Control-Allow-Credentials
  5. Youtube : CORS in 100 Seconds
CORS - クロスオリジンAJAX呼び出しのためのSOP補完ポリシー
Author
Aaron
Posted on
Licensed Under
CC BY-NC-SA 4.0
CC BY-NC-SA 4.0
同じカテゴリーの関連記事
最新記事
LLMフィルターが奪う会話の筋肉とコミュニケーション様式
会話における無礼さを濾過し、洗練された回答を生成するLLMツールが日常化した現代において、私たちは本当に思慮深い会話をしているのだろうか?リアルタイムのコミュニケーションにおける数多くの失敗を通じて磨かれるべき会話能力が、外部ツールに依存することで退化している現象と、それがもたらす社会的な不安や世代間の行動様式の変化について考察する。
シニア採用における年俸交渉の最適なタイミングと戦略
年俸交渉は単なる数字の交換ではなく、心理的な駆け引きとタイミングが重要です。本稿では、企業側にとって、候補者が計算的な態度を取りがちな最終合格後よりも、採用プロセスの初期段階から段階的に交渉を進めることが、なぜより効率的であり、率直な情報の共有に繋がるのかを考察します。
法治主義の限界と人間の多様性
全ての人間の行為を単一の法体系で規制できるという信念は、傲慢であるかもしれない。この記事は、中世の階層的な統制から脱却し、現代の無限の自由を手に入れた人類が直面する法治主義の逆説と、多様性という名のもとに深化する社会的強制力と他者への悪魔化現象を鋭く分析する。
토스트 예시 메세지