同一オリジン ポリシー

Mariko Kosaka

同一オリジン ポリシーは、あるオリジンのドキュメントとスクリプトが別のオリジンのリソースとやり取りする方法を制限するブラウザのセキュリティ機能です。

ブラウザは、複数のサイトから一度にリソースを読み込んで表示できます。同時に複数のタブを開いたり、異なるサイトの複数の iframe がサイトに埋め込まれている場合があります。これらのリソース間のやり取りに制限がなく、スクリプトが攻撃者によって不正使用されると、スクリプトによってユーザーのブラウザですべてが公開されるおそれがあります。

同一オリジン ポリシーでは、別のオリジンから読み込まれたリソースへの読み取りアクセスをブロックすることで、この問題を回避できます。「とにかく待ってください」 「私は常に他のオリジンから画像やスクリプトを読み込んでいます」ブラウザでは、いくつかのタグで異なる生成元のリソースを埋め込むことができます。このポリシーのほとんどは過去のアーティファクトであり、サイトが iframe を使用したクリックジャッキングなどの脆弱性にさらされる可能性があります。コンテンツ セキュリティ ポリシーを使用して、これらのタグのクロスオリジン読み取りを制限できます。

同一オリジンとは

送信元は、スキーム(HTTP や HTTPS などのプロトコルとも呼ばれます)、ポート(指定されている場合)、ホストによって定義されます。2 つの URL で 3 つがすべて同じである場合、それらは同じオリジンとみなされます。たとえば、http://www.example.com/foohttp://www.example.com/bar と同じオリジンですが、スキームが異なるため https://www.example.com/bar ではありません。

許可される対象とブロックされる対象

一般に、クロスオリジン リソースの埋め込みは許可されますが、クロスオリジン リソースの読み取りはブロックされます。

iframe 通常、クロスオリジン埋め込みは(X-Frame-Options ディレクティブに応じて)許可されますが、クロスオリジン読み取り(JavaScript を使用して iframe 内のドキュメントにアクセスするなど)は許可されません。
CSS クロスオリジンの CSS は、CSS ファイルの <link> 要素または @import を使用して埋め込むことができます。正しい Content-Type ヘッダーが必要になる場合があります。
フォーム クロスオリジン URL は、フォーム要素の action 属性値として使用できます。ウェブ アプリケーションは、クロスオリジンのデスティネーションにフォームデータを書き込むことができます。
画像 クロスオリジン画像の埋め込みは許可されます。ただし、クロスオリジンの画像データの読み取り(JavaScript を使用してクロスオリジンの画像からバイナリデータを取得するなど)はブロックされます。
マルチメディア クロスオリジンの動画と音声は、<video> 要素と <audio> 要素を使用して埋め込むことができます。
筆跡 クロスオリジン スクリプトを埋め込むことはできますが、特定の API(クロスオリジン取得リクエストなど)へのアクセスはブロックされる可能性があります。

TODO: DevSite - 思考とチェックの評価

クリックジャッキングを防ぐ方法

クリックジャッキング
図: 3 つの個別のレイヤ(ベースサイト、iframed サイト、透明なボタン)で示されたクリックジャッキング メカニズム。

「クリックジャッキング」と呼ばれる攻撃では、iframe にサイトを埋め込み、別のリンク先にリンクする透明なボタンをオーバーレイします。ユーザーは、攻撃者にデータを送信している間に、アプリケーションにアクセスしていると思わせてしまいます。

他のサイトからの iframe への埋め込みをブロックするには、frame-ancestors ディレクティブを使用してコンテンツ セキュリティ ポリシーを HTTP ヘッダーに追加します。

また、HTTP ヘッダーに X-Frame-Options を追加することもできます。オプションのリストについては、MDN をご覧ください。

まとめ

ウェブ上のセキュリティの門番としてブラウザが果たす役割について、少しだけ安心できたでしょうか。ブラウザはリソースへのアクセスをブロックすることで安全を確保しようとしますが、アプリケーション内のクロスオリジン リソースにアクセスしたい場合もあります。次のガイドでは、クロスオリジン リソース シェアリング(CORS)の概要と、信頼できるソースからクロスオリジン リソースの読み込みが許可されていることをブラウザに伝える方法について説明します。