第1回:ブラウザの絶対防壁「同一オリジンポリシー」
〜CORSエラーという名の厳格なる門番〜
導入:見えない「盾と矛」の戦争
Webの歴史は、より便利でリッチな体験を追求する「光の歴史」であると同時に、悪意あるハッカー(攻撃者)とそれを防ぐエンジニアたちの果てしない 「盾と矛の戦争」 の歴史でもあります。
私たちが毎日インターネットを安全に使えるのは、ブラウザというソフトウェアの中に、ハッカーの罠を弾き返すための分厚い防壁(ルール)がいくつも張り巡らされているからです。
新シリーズ「Webセキュリティ攻防戦」の第1回は、すべてのWebセキュリティの原点にして最大の鉄則。
そして、現代のWebエンジニアたちを最も苦しめる(?)強固な防壁、「同一オリジンポリシー(SOP)」 のお話です。
1. もし「壁」が存在しなかったら?(恐怖のシナリオ)
同一オリジンポリシー(SOP:Same-Origin Policy)の仕組みを理解するために、まずは 「もしこのルールが存在しなかったら、どんな地獄が起きるか」 を想像してみましょう。
あなたは今、ブラウザの「タブA」で自分のメインバンク(銀行)のサイトにログインし、口座残高を確認しています。
その状態で、ふと気になって「タブB」を開き、ネットサーフィンで見つけた面白そうなサイト(実はハッカーが作った悪意のあるサイト)を開いたとします。
もしブラウザにルールの壁がなかったら、どうなるでしょうか?
タブBで動いているハッカーのJavaScript(プログラム)は、あなたのタブA(銀行サイト)を勝手に覗き見ることができてしまいます。
「あ、この人銀行にログインしてるな。ちょっと口座番号と残高の数字を読み取って、ハッカーのサーバーに送信しておこう」
ブラウザを開いているだけで、個人情報も、会社の機密情報も、すべて別タブの悪質サイトから筒抜けになってしまう……。Webはまさに「泥棒に入られ放題」の無法地帯になってしまいます。
2. 絶対防壁「同一オリジンポリシー(SOP)」の誕生
この悪夢を防ぐために、ブラウザには大昔から 「同一オリジンポリシー(SOP)」 という極めて厳格なルールが組み込まれています。
ルールは非常にシンプルです。
「出身地(オリジン)が違う者同士は、絶対にデータを読み書きしてはいけない」
では、この「出身地(オリジン)」とは何で決まるのでしょうか? 以下の3つの要素が 「すべて完全一致」 した場合のみ、同じオリジンと見なされます。
-
スキーム(通信手段):
httpなのかhttpsなのか -
ホスト(ドメイン):
www.example.comのような住所 - ポート番号: (通常は省略されますが、httpなら80、httpsなら443)
たとえば、銀行が https://bank.com だとします。
ハッカーのサイト https://evil.com とは「ホスト」が違うので、完全に別人(別オリジン)です。ブラウザは分厚いコンクリートの壁を下ろし、ハッカーのJavaScriptが銀行のデータを読み取るのを 強制的にブロック(遮断) します。
このSOPという絶対防壁があるおかげで、私たちはタブを何十個開いても、安全にインターネットを楽しむことができるのです。
3. 現代開発者の絶望「CORSエラー」
SOPはユーザーを守る最強の盾でした。しかし2010年代以降、Webが「SPA(シングルページアプリケーション)」へと進化し、フロントエンドとバックエンドが切り離されると、この厳格すぎる壁が 「開発者自身の首を絞める」 ことになります。
現代のWeb開発では、こんな構成がよくあります。
- フロントエンド(画面):
https://app.my-service.com - バックエンド(データ):
https://api.my-service.com
フロントエンドのJavaScriptが、バックエンドに「ユーザーのデータをちょうだい(Ajax通信)」とお願いをします。
しかしブラウザは、冷酷にこう言い放ちます。
「ホスト名(app と api)が違うな。お前たちは別オリジンだ。通信をブロックする!」
「いやいや、どっちも俺が作った自社サービスだよ! 怪しいサイトじゃないよ!」
開発者がいくら叫んでも、ブラウザは問答無用で通信を遮断し、開発者ツールの黒い画面(コンソール)に、憎き真っ赤なエラーメッセージ を吐き出します。
Access to XMLHttpRequest at '...' from origin '...' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
これが、世界中のエンジニアの時間を奪い、絶望の淵に叩き落としてきた 「CORS(コルス)エラー」 の正体です。
4. 門番を通るためのパスポート「CORS」
CORS(Cross-Origin Resource Sharing:オリジン間リソース共有)は、エラーの名前ではありません。
SOPという分厚い壁に、 「安全が確認できた相手だけを通す特別な扉(例外ルール)」 を作るための仕組みのことです。
ブラウザの門番を納得させるには、フロントエンドが頑張るのではなく、 データを渡す側(バックエンドのサーバー)が許可証(パスポート)を発行 してあげなければなりません。
バックエンドのサーバーの設定で、通信のヘッダーにこう書き加えます。
Access-Control-Allow-Origin: https://app.my-service.com
(翻訳:「このサーバーは、app.my-service.com というオリジンからのアクセスなら、特別に許可するよ!」)
このパスポートを見たブラウザの門番は、「なるほど、サーバー本人が許可を出しているなら通してやろう」と壁を開けてくれます。
これでようやく、真っ赤なCORSエラーは消え去り、平和な通信が行われるのです。
おわりに:エラーは「守護者」の証
CORSエラーが出ると、つい「なんだこの面倒くさい仕様は!」とブラウザに怒りをぶつけたくなるのがエンジニアの性(さが)です。
しかし、なぜブラウザがこれほどまでに過保護で、厳格な門番として振る舞うのか。
それは、一歩間違えればユーザーの全財産や個人情報が奪われてしまう、危険なWebの世界から私たちを守るためなのです。真っ赤なエラー文字は、ブラウザが正常にあなたを守っているという「誇り高き盾の証明」でもあります。
次回予告
SOPの壁によって、他人のサイトを勝手に覗き見ることはできなくなりました。
「これでWebは安全だ!」……ハッカーたちはそんな甘い相手ではありませんでした。
「覗き見がダメなら、ユーザー本人のフリをして、罠を踏ませて操作させればいい」
ログインしているユーザーの「信頼」を逆手に取り、見えないところで勝手に犯罪予告を書き込ませたり、勝手に商品を買わせたりする卑劣な罠。
次回、第2回。
「善意を装う罠『CSRF』 〜見えない攻撃と、秘密の合言葉(トークン)〜」
📚 参考文献・出典
本記事で解説したセキュリティルールの詳細は、以下の公式ドキュメントに基づいています。
-
同一オリジンポリシー (Same-Origin Policy)
-
MDN Web Docs (Mozilla):
- Web開発者にとってのバイブルであるMDNの公式解説。どのような条件でオリジンが「同一」と判定されるか、厳密なルールが記載されています
- 同一オリジンポリシー - MDN Web Docs
-
MDN Web Docs (Mozilla):
-
オリジン間リソース共有 (CORS)
-
MDN Web Docs (Mozilla):
- CORSの仕組みと、
Access-Control-Allow-OriginなどのHTTPヘッダーによる制御方法についての詳細な技術ドキュメントです - オリジン間リソース共有 (CORS) - MDN Web Docs
- CORSの仕組みと、
-
MDN Web Docs (Mozilla):
🤖 執筆協力
本記事の構成案作成および推敲には、生成AIのアシストを活用しています。