前回のCookieのDomain属性の記事に引き続き、某所での勉強会でまた理解が怪しいことが出てきたので、考えてまとめてみました。
今回は同一オリジンポリシーです。同一オリジンポリシーがなんなのか、ということ自体は問題な理解できたのですが、なぜそれが必要なのか、ということに関してすっきり納得できるようには理解できませんでした。
結論
- 攻撃者はJavaScriptによりブラウザを強制的に操作することができる。
- それにより攻撃者のではなく、ブラウザの権限で攻撃者の意図する操作が行われる。
- そのため同一オリジンポリシーがない場合、本来権限がないため攻撃者がアクセスできないはずの別オリジンのデータを盗み出すことができる。
というのが同一オリジンポリシーが必要な理由ではないかと思われます。
同一オリジンポリシーはなにを制限していて、なにを制限していないか
同一オリジンポリシーは、以下のものを制限しているようです。
- XMLHttpRequestによる別オリジンへのリクエスト。
- frame, iframeで表示している別オリジンのドキュメントへのJavaScriptからのアクセス。
- Canvasによる別オリジンの画像の読み込み。
逆に、以下のようなJavaScript以外による別ドメインへのアクセスは制限されていないようです。
- a要素のクリックによる別オリジンのURLへの移動。
- location.hrefによる別オリジンのURLへの移動。
- form要素のサブミットによる別オリジンのURLへのPOSTリクエスト。
- img, script, style要素による別オリジンのデータの読み込み。
もし同一オリジンポリシーがなかったら
別オリジンにXMLHttpRequestできたり、別オリジンの任意のページをframe, iframe経由で好きに読み込むことができたら、いったいどうなるのか、考えてみます。
まず悪意のあるJavaScriptが仕込まれた罠サイトがあるとします。JavaScriptの実行は、一応ブラウザの設定で無効にすることもできたりしますが、最近はもうほとんどそのようなことをする人はいないと思うので、あるサイトにアクセスするということは、そこにあるJavaScriptを実行されることと同義と考えていいと思います。
同一オリジンポリシーがなければ、XMLHttpRequestはHTTPリクエストを自由に送って、XMLに限らずいろんなものを取得できます。Cookieも普通に送信されるので、ブラウザでログインしていたら、ログインしている状態でそのサイトに自由にアクセスできてしまいます。
たとえばECサイトの送付先住所が掲載されているページにリクエストを送れば、住所を取得できてしまいます。
パスワードやクレジットカード情報が直接表示されるようなページは現在は基本的にありませんが、それ以外の、メールアドレスや住所氏名、電話番号といった情報は大抵普通に表示されています。これらの情報がすべて盗み出されてしまいます。
frame, iframeの場合もおそらく同様です。Canvasは少し勝手が違いますが、画像共有サイトにアップロードしてはいるが、非公開にしている画像などが盗まれることになると考えられます。
このような被害を防ぐために、同一オリジンポリシーが必要なのでしょう。
同一オリジンポリシーの制限がなくても安全な機能は、なぜ安全か
ついでに、同一オリジンポリシーの制限がない機能に、なぜ制限がないかについても考えてみます。
a要素、location.hrefについては簡単で、別オリジンのページに移動させられることは、単純にそれほど危険ではないからでしょう。前者に関しては基本的には能動的な操作さえ必要です。
img, script, style要素については少し混乱しますが、実は同様で、ブラウザがこれらの要素から別オリジンのドキュメントにアクセスさせられはしますが、そのアクセス結果を罠サイト側から知ることはできません。1
例外
- form要素のサブミットによるPOSTリクエストは同一オリジンポリシーによる制限がありませんが、これは完全に安全ではなく、CSRF脆弱性と関連します。今回の本題ではないため省略します。
- script要素は完全に安全ではなく、秘匿情報がJavaScript内に出力されている場合に盗まれる可能性があります。これも省略します。
参考
体系的に学ぶ 安全なWebアプリケーションの作り方 この本の勉強をしています。
画像とキャンバスをオリジン間で利用できるようにする - HTML: HyperText Markup Language | MDN Canvasとオリジンの話。
この記事のライセンス
この文書はCC BY(クリエイティブ・コモンズ表示4.0国際ライセンス)で公開します。
-
ただしscript要素に関しては例外があります。別オリジンのJavaScriptを読み込んだ場合、そのJavaScriptで定義された変数を罠サイト側で使用できるため、JavaScript内に秘匿情報があれば盗み出されることがあります。 ↩