2018-01-06
SOP(Same Origin Policy)とCORS(Cross Origin Resource Sharing)について調べた
SOP(Same Origin Policy)の理解が怪しいなぁと思ったのでちゃんとした仕様を調べた。
同時にCORS(Cross Origin Resource Sharing)についても調べることになったのでまとめて整理した。
SOP(Same Origin Policy: 同一生成元ポリシー)
- Webブラウザなどのセキュリティ機能の1つ
- ある オリジン から読み込まれた文書やスクリプトについて、そのリソースから他の オリジン のリソースにアクセスできないように制限するもの
※ 参考:https://developer.mozilla.org/ja/docs/Web/Security/Same-origin_policy
オリジンとは
スキーム、ポート、ホストがそれぞれ等しいものが、同じオリジンと見なされる
http://domain-a.com/dir/page.html
をベースとした場合、次のようになる。
(o) http://domain-a.com/dir2/other.html
(o) http://domain-a.com/dir/inner/another.html
(x) https://domain-a.com/secure.html
-> スキームが異なる
(x) http://domain-a.com:81/dir/etc.html
-> ポートが異なる
(x) http://domain-b.com/dir/other.html
-> ホストが異なる
※ 補足
- IPアドレスは見ていない
- パスが異なるだけのものは問題ない
※ 参考:https://developer.mozilla.org/ja/docs/Web/Security/Same-origin_policy#Definition_of_an_origin
制限されるもの
- XMLHTTPRequestによる取得
- スクリプトによる別のオリジンである
iframe
やwindow
に対する操作 - Canvasへの一部の操作
制限されないもの
SOP(同一生成元ポリシー)には許されているものがいくつかある。 以下、異なるオリジンに埋め込むことができるリソースの例。
<script src="..."></script>
によるJavaScript<link rel="stylesheet" href="...">
によるCSS<img>
による画像<video>
,<audio>
によるメディアファイル<object>
,<embed>
,<applet>
によるプラグイン@font-face
で指定されたフォント<frame>
,<iframe>
に関連する様々なもの<form>
からの送信
異なるオリジンへのアクセスを許可する方法
- かつてはJSONPという手法が使われていた(JSONPについては省略)
- 現在では CORS を使用することが推奨されているようだ
CORS (Cross Origin Resource Sharing)
- SOPはセキュリティ上重要な仕組みだが、まっとうなWebアプリケーション開発者にとってはオリジンをまたいだアクセスが必要になるケースが多かった。そこでCORSが登場した
- Webサーバがドメインをまたぐアクセスを制御する方法を規定することで、ドメイン間の安全な通信を保証する
- つまり、CORSの仕様に則れば、ドメインをまたいだアクセス(クロスオリジンHTTPリクエスト)ができるようになる
※ 参考:https://developer.mozilla.org/ja/docs/Web/HTTP/HTTP_access_control#Overview
CORSのパターン
大きく2つのパターンがある
- (1) simple cross-origin request
- (2) actual request(プリフライトがある)
simple cross-origin requestになる条件は以下の通り
- HTTPメソッドがGET,POST,HEADのいずれかである
- HeaderがAccept,Accept-Language, Content-Language, Content-Type以外を含まない
- Content-Typeを含む場合、その値がapplication/x-www-form-urlencoded, multipart/form-data, text-plainのいずれかである
上記の条件に合致しない場合はactual requestというプリフライトが必要なパターンになる
※ 参考:『Real World HTTP』10章
Real World HTTP ―歴史とコードに学ぶインターネットとウェブ技術
amazon.co.jp
プリフライトリクエストとは
- 実際の通信の前に、権限確認目的で送信するリクエストのこと
- プリフライトリクエストはHTTPメソッドのOPTIONSを使って送信される
- リクエストには以下のヘッダを含む
- Access-Control-Request-Method: 通信を許可してもらいたいメソッド
- Access-Control-Request-Headers: 許可して欲しいヘッダー(カンマ区切り)
- Origin: 通信元のウェブページのドメイン名
- プリフライトリクエストは、リクエスト前に毎回送信されるわけではない。通信内容を一定期間キャッシュすることができる。キャッシュ期間を制御するには以下のヘッダを使う
- Access-Control-Max-Age
※ 参考:『Real World HTTP』10章
<< 前の記事属人化の排除と責任感のトレードオフについて