はじめに
Web セキュリティの話題で必ず登場する Same-Origin Policy(SOP) と CORS(Cross-Origin Resource Sharing)。
しかし現場では、次のような誤解が後を絶ちません。
- 「CORS を設定しているから CSRF は大丈夫」
- 「Origin を見ているから外部サイトは叩けない」
- 「
Access-Control-Allow-Origin: *は便利だからOK」
結論から言うと、これらはすべて危険な誤解です。
本記事では、
- SOP と CORS の正しい役割
- なぜそれらが CSRF や情報漏洩を防げないのか
- 実際に発生する CORS / SOP Bypass パターン
を 攻撃者視点で整理します。
1. Same-Origin Policy(SOP)とは何か
SOP の定義
**Same-Origin Policy(同一オリジンポリシー)**とは、
ブラウザが「異なるオリジンのリソースを JavaScript から直接操作・読み取りすること」を制限する仕組み
です。
オリジン = 以下 3 点がすべて一致
- スキーム(http / https)
- ホスト
- ポート
https://example.com ✔ 同一オリジン
https://api.example.com ✖ ホスト違い
http://example.com ✖ スキーム違い
SOP が防ぐもの・防がないもの
| 内容 | SOP |
|---|---|
| クロスサイトでレスポンスを読む | 防ぐ |
| クロスサイトリクエストを送る | 防がない |
| CSRF | 防がない |
<form> / <img> / <script>
|
防がない |
重要
SOP は「読むこと」を防ぐだけで、「送ること」は止めない
これが CSRF が成立する根本理由です。
2. CORS とは何か(よくある誤解)
CORS の本質
CORS はセキュリティ機構ではなく、例外許可ルールです。
サーバーが「このオリジンから来た JS なら、レスポンスを読んでもいい」とブラウザに伝える仕組み
Access-Control-Allow-Origin: https://frontend.example
CORS はブラウザ限定
- curl / Python / SSRF には一切影響しない
- WAF やファイアウォールではない
CORS と CSRF の決定的な違い
| 観点 | CORS | CSRF |
|---|---|---|
| 守る対象 | レスポンスの読み取り | 不正な状態変更 |
| 主語 | JavaScript | ブラウザ |
| Cookie 制御 | 条件付き | 自動送信 |
CORS があっても CSRF は成立する
3. SOP / CORS Bypass の全体像
SOP / CORS の Bypass は大きく 4 系統に分かれます。
A. SOP の仕様上の限界(CSRF 等)
B. CORS 設定ミス
C. ブラウザ挙動・互換仕様
D. XSS による SOP 崩壊
4. A. SOP は最初から CSRF を防げない
典型的 CSRF
<form action="https://victim.com/change-email" method="POST">
<input name="email" value="attacker@evil.com">
</form>
<script>document.forms[0].submit()</script>
- ブラウザが Cookie を自動送信
- SOP は 一切介入しない
- レスポンスを読まなくても攻撃成立
CSRF は SOP の想定外
5. B. 危険な CORS 設定ミス
5.1 Access-Control-Allow-Origin: *
header("Access-Control-Allow-Origin: *");
これはよく見かけますが、
- Cookie は送られない
- 認証付き CSRF を直接引き起こすわけではない
しかし、
- 公開すべきでない API
- 内部情報を返すエンドポイント
では 情報漏洩の原因になります。
5.2 Origin 反射 + Credentials(最悪)
Access-Control-Allow-Origin: https://evil.com
Access-Control-Allow-Credentials: true
サーバーが Origin をそのまま返す場合:
fetch("https://victim.com/api/me", {
credentials: "include"
})
結果:
- Cookie が送信される
- レスポンスを JS が読める
- CSRF + 情報窃取が同時成立
これは CORS Bypass の代表例
5.3 子ドメイン信頼ミス
Access-Control-Allow-Origin: https://*.example.com
攻撃者が:
- サブドメインを取得
- DNS を乗っ取る
- 静的ホスティングを使う
→ 正規オリジンとして扱われる
6. C. ブラウザ仕様・歴史的 Bypass
Chrome SameSite 2 分ルール
- Cookie 設定直後 2 分以内
-
SameSite=Laxでも POST 送信される - 一時的に
SameSite=Noneのように振る舞う
短時間 CSRF 窓
7. D. XSS による SOP 完全崩壊
XSS が成立した瞬間:
fetch("/api/secret")
- 完全に同一オリジン
- SOP / CORS は無意味
- Cookie・Token 全取得可能
XSS は SOP / CORS の核兵器
8. 攻防まとめ表
| 攻撃 | SOP | CORS |
|---|---|---|
| CSRF | ❌ 防げない | ❌ 防げない |
| JSONP | ❌ | ❌ |
| CORS 誤設定 | ❌ | ❌ |
| XSS | ❌ | ❌ |
| SSRF | ❌ | ❌ |
9. 防御側 Checklist
- CSRF Token + SameSite の併用
- CORS は 最小限ホワイトリスト
- Origin の反射禁止
- Credentials は本当に必要か再検討
- 子ドメインは信用しない
- XSS 対策が最優先
まとめ
SOP は最低限の安全柵であり、セキュリティ対策ではない
CORS は許可機構であって、防御機構ではない
「SOP があるから」「CORS を設定しているから」という理由で
CSRF / 情報漏洩を軽視した瞬間、攻撃は成立する。