🐙

【セキュリティ】Same-Origin Policyとは

に公開1

はじめに

Same-Origin Policy(SOP)という言葉を聞いたことはあるでしょうか?
これはセキュリティの根幹を支える重要な概念で、このポリシーがなければ、悪意のあるWebサイトが別のサイトのデータを自由に読み取ったり、操作したりできてしまいます。
例えば、ログインしている銀行サイトの情報を、別のタブで開いた悪意のあるページから奪われる可能性があります。

この記事では、Same-Origin Policyの仕組みや必要な理由など、わかりやすく解説していきます。

Same-Origin Policy(SOP)とは

Same-Origin Policyは、異なるオリジン(ドメイン)間のリソースアクセスを制限するブラウザのセキュリティ機構のことです。
オリジン(Origin)とは、
プロトコル(http/https) + ドメイン(example.com) + ポート(80, 443など) の組み合わせで定義されます。

同じオリジン からのリクエストは許可されますが、異なるオリジン からのリクエストはデフォルトでブロックされます。


https://shukapin.com/infographicIT/origin-policy より引用

ブラウザは、このルールに基づいて JavaScriptによる他のオリジン(ドメイン)へのアクセスを制限し、勝手にデータを読み取られないようにしています。

Same-Origin Policyが適用される代表的なケース

(1)AJAX(Fetch / XMLHttpRequest)での異なるオリジンへのリクエスト


https://dotnettutorials.net/lesson/cors-in-asp-net-core-web-api/ より引用

デフォルトでは、fetch() や XMLHttpRequest で別のドメインにリクエストを送信できません。

(例)https
fetch("https://api.example.com/data")
  .then(response => response.json())
  .then(data => console.log(data));

CORSエラー(Cross-Origin Request Blocked) が発生し、ブロックされます。
(※ただし、CORSが適切に設定されていれば許可される場合があります)
※CORSについては別記事をご参照ください。

(2)<iframe> での別オリジンのページ読み込み

<iframe> で別のサイトを埋め込んだ場合、親ページから子ページのDOMにアクセスできません。

<iframe src="https://bank.com/login"></iframe>
<script>
  const iframe = document.querySelector("iframe");
  // 以下の操作は Same-Origin Policy でブロックされる
  console.log(iframe.contentWindow.document.body);
</script>

このコードは SecurityError を引き起こします。

(3)document.cookie や localStorage のアクセス制限

Cookie や Web Storage(localStorage / sessionStorage)は、オリジンごとに隔離されています。
example.com で保存したデータを another-site.com から読み取ることはできません。

Same-Origin Policy の例外と回避策

Same-Origin Policyはセキュリティ上重要ですが、現実のWeb開発では 異なるオリジン間でデータをやり取りする必要があります。そのための仕組みがいくつか存在します。

(1)CORS(Cross-Origin Resource Sharing)

サーバー側で「このオリジンからのアクセスを許可する」と明示的に宣言することで、異なるオリジン間の通信を可能にします。

例(サーバー側の設定)
Access-Control-Allow-Origin: https://myapp.com

https://myapp.com からのリクエストを許可します。

(2)プロキシサーバーを経由する

バックエンドサーバーを経由してリクエストを中継することで、ブラウザのSame-Origin Policyを回避します。

Same-Origin Policy が防ぐセキュリティリスク

  1. 他のタブで開いているWebサイトの情報を盗む
    (例)銀行サイトのセッションCookieを奪われる
  2. 悪意のあるサイトが、ユーザーのログイン状態を悪用する
    <iframe> で表示したページを操作され、フィッシング詐欺に利用される

Same-Origin Policyは、「ブラウザ上で動作するJavaScriptが、許可されていないデータにアクセスするのを防ぐ」 ことで、これらの脅威からユーザーを守っています。

まとめ

Same-Origin Policyは、異なるオリジン間のアクセスを制限するブラウザのセキュリティ機構のことで、「オリジン」 は プロトコル + ドメイン + ポート で定義されることが理解できたでしょうか?
AJAX、iframe、Cookie/Storageアクセスなどに適用されますが、CORSやプロキシサーバーを使うことで、安全に異なるオリジンと通信できるようになります。
Same-Origin Policyがあることによって、CSRFやセッションハイジャックなどの攻撃を事前に防いでいることを理解しておきましょう!
最後までお読みいただき、ありがとうございました。

参考・画像引用元URL

https://shukapin.com/infographicIT/origin-policy
https://dotnettutorials.net/lesson/cors-in-asp-net-core-web-api/
https://medium.com/@tbgarza2/basics-of-same-origin-policy-and-cors-1e77882a43b
https://www.cobalt.io/blog/browser-security-same-origin-policy-vs-cors-misconfigurations
https://yamory.io/blog/about-cors

Discussion

ockeghemockeghem

デフォルトでは、fetch() や XMLHttpRequest で別のドメインにリクエストを送信できません。

ここは不正確です。シンプルリクエストの要件を満たしていれば、相手先の許可がなくても、HTTPリクエストは送信できます。そのレスポンスをJavaScriptでは受け取れないというのがCORSのデフォルトの挙動です。参照されているページや図も、このあたりの説明は不十分ですね。