はじめに
Access to XMLHttpRequest at 'http://example.com ' from origin 'http://sample.jp ' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested resource
JavaScriptを使用している方は、上記のエラーを目にしたことがあると思います。
エラー内容を要約すると「あなたのサイトからのリクエストは許可していません」といった意味で、JavaScriptでXMLHttpRquest
やFetch API
を使ってAJAX通信をする際に起こりうるものとなります。
これは同一オリジンポリシー(Same-Origin Policy)という規約に違反していることが根本の原因なのですが、この同一オリジンポリシーというものを理解するべく、なるべく簡潔にまとめたいと思います。
同一オリジンポリシーとは
ウェブブラウザに実装された、リソース取り扱いに関するセキュリティ上の仕組みで「同一生成元ポリシー」や「同一源泉ポリシー」とも呼ばれます。
スキーム(プロトコル)、ホスト、ポートの3つの組み合わせをオリジンと呼び、これらが同じ場合は同一のオリジンとみなし、同じ保護範囲のリソースとして取り扱うというものです。
つまり、異なるオリジン(クロスオリジン)からのリソースへのアクセスを制限するという仕組みになります。
オリジンとは
スキーム(プロトコル)、ホスト、ポートから構成されるもので、それぞれはURLの一部分を指しています。
http://store.example.com:80/foo
上記のURLを例に挙げた場合は以下のようになります。
- スキーム(プロトコル) =
http
- ホスト =
store.example.com
- ポート =
80
これらが1つでも異なる場合は異なるオリジンとして判断されます。
メリット
同一オリジンポリシーが存在しない場合どうなるのか。
例えばユーザーがECサイトにログインしている状態で別の悪意あるサイトを閲覧した場合、ECサイトに登録された個人情報を悪意あるサイトから取得できてしまいます。
このようにサイトをまたがった攻撃は「受動的攻撃」と呼ばれ、代表的なものにクロスサイト・スクリプティング(XSS)やクロスサイト・リクエストフォージェリ(CSRF)があります。
同一オリジンポリシーによって受動的攻撃を防止していますが、もちろん完璧ではなく、Webサイト・アプリケーション自体に脆弱性があれば受動的攻撃を受ける場合があります。
制限の対象となるもの・ならないもの
「異なるオリジンからのリソースへのアクセスを制限する」と説明しましたが、別オリジンの画像やJavaScriptの読み込みができることから分かるように、同一オリジンポリシーによって制限されるもの・されないものが存在します。
制限の対象となるもの
-
JavaScriptでの非同期通信
厳密には「リクエストはできるがレスポンスを取得できない」という制限で、クロスオリジンでは許可された場合にしかレスポンスを取得することはできません。 -
Canvas
異なるのオリジンから読み込まれた画像・データをCanvas内に描画するとCanvasは汚染(taint)されます。
汚染されたCanvasではデータへのアクセス(getImageData()
、toBlob()
、toDataURL()
)が制限されます。 -
Web Storage
Web Storageなどのブラウザー内部に保存されるデータへのアクセスはオリジン単位で権限が分かれているため、異なるオリジンに属するストレージを読み書きすることはできません。 -
X-Frame-Options
レスポンスヘッダーにSAMEORIGIN
が設定されている場合、異なるオリジンでは<iframe>
などを使った別サイトコンテンツの埋め込みができません。
制限の対象とならないもの
-
<scrip>
で読み込まれたJavaScript -
<link>
で読み込まれたCSS -
@font-face
で読み込まれたWebフォント
注)クロスオリジンでは許可されないブラウザもあります。 -
<img>
で読み込まれた画像(PNG、JPEG、GIF、BMP、SVGがサポート対象) -
<video>
、<audio>
タグで読み込まれたメディアファイル -
<object>
、<embed>
タグで埋め込まれたリソース -
<iframe>
、<frame>
での別サイトコンテンツの読み込み
注)コンテンツの読み込みは許可されますが、コンテンツ内のドキュメントにはアクセスできません。
オリジン以外をベースに制限を設けているもの
- Cookie
Cookieに関してはスキーム、ポートは関係ありません。 - HTTP認証
クロスオリジンのアクセスを許可するには
異なるオリジンへのアクセスを許可するにはオリジン間リソース共有(CORS)を使用します。
詳細は割愛しますが、CORSを使用することで特定のオリジンからのリクエストに対してはリソースへのアクセスを許可する、といったルールの制定が可能になります。
参考URL
-
同一オリジンポリシー(MDN)
https://developer.mozilla.org/ja/docs/Web/Security/Same-origin_policy -
同一生成元ポリシー(Wikipedia)
https://ja.wikipedia.org/wiki/%E5%90%8C%E4%B8%80%E7%94%9F%E6%88%90%E5%85%83%E3%83%9D%E3%83%AA%E3%82%B7%E3%83%BC -
Same-Origin Policy とは何なのか。
http://hasegawa.hatenablog.com/entry/20130330/p1 -
画像とキャンバスをオリジン間で利用できるようにする(MDN)
https://developer.mozilla.org/ja/docs/Web/HTML/CORS_enabled_image