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章
プリフライトリクエストとは
- 実際の通信の前に、権限確認目的で送信するリクエストのこと
- プリフライトリクエストは HTTP メソッドの OPTIONS を使って送信される
- リクエストには以下のヘッダを含む
- Access-Control-Request-Method: 通信を許可してもらいたいメソッド
- Access-Control-Request-Headers: 許可して欲しいヘッダー(カンマ区切り)
- Origin: 通信元のウェブページのドメイン名
- プリフライトリクエストは、リクエスト前に毎回送信されるわけではない。通信内容を一定期間キャッシュすることができる。キャッシュ期間を制御するには以下のヘッダを使う
- Access-Control-Max-Age
※ 参考:『Real World HTTP』10章
h3pei
<< 前の記事属人化の排除と責任感のトレードオフについて