はじめに
CSRF(Cross-Site Request Forgery)対策として、
「Referer ヘッダが自分のドメインなら OK」
という実装を、今でも見かけることがあります。
一見それっぽく見えますが、結論から言うと:
Referer 単体の CSRF 対策は信用してはいけない
本記事では、
- Referer ヘッダの仕組み
- Referer ベース CSRF 防御の前提
- 実際に成立する Referer Header Bypass
- なぜ単体防御として破綻しているのか
- 正しい防御設計
を 攻撃者視点+防御者視点で整理します。
Referer ヘッダとは
Referer ヘッダは、HTTP リクエストにおいて:
「このリクエストは、どのページから遷移してきたか」
をサーバへ通知するためのヘッダです。
POST /transfer HTTP/1.1
Host: bank.example
Referer: https://bank.example/dashboard
Cookie: session=abc123
この情報を使い、
- 正規ページ → 正規操作
- 外部サイト → 不正操作
を判別しよう、というのが Referer ベース CSRF 対策の発想です。
Referer を使った CSRF 防御の典型例
多くの実装は、次のようなロジックを持ちます。
if Referer が自ドメインなら許可
else 拒否
あるいはコード上では:
if referer and referer.startswith("https://bank.example"):
allow()
一見すると合理的ですが、前提が崩れるケースが非常に多いのが問題です。
なぜ Referer は信用できないのか
1. Referer は「必須ヘッダではない」
HTTP 仕様上、Referer は 存在しなくても正常です。
以下のリクエストは合法です:
POST /transfer HTTP/1.1
Host: bank.example
Cookie: session=abc123
- Referer が「ない」=攻撃とは限らない
- サーバ側が「必ず入る」と思うのが間違い
2. プライバシー機能・拡張機能で簡単に消える
以下は珍しくありません:
- 広告・トラッカー防止拡張
- Brave / Tor Browser
- セキュリティプロキシ
- 企業ネットワーク
結果:
- Referer が送られない
- あるいは書き換えられる
正規ユーザーでも Referer 欠落が起きる
3. HTML / Meta タグで意図的に消せる
攻撃者は、HTML だけで Referer を消せます。
<meta name="referrer" content="no-referrer">
または:
<a href="https://bank.example/transfer"
referrerpolicy="no-referrer">
結果:
- リクエストは送信される
- Referer は空
JavaScript すら不要
4. HTTPS → HTTP で自然に落ちる
ブラウザ仕様により:
https://evil.com → http://bank.example
この場合、Referer が送られないことがあります。
👉 攻撃でなくても欠落
Referer Header Bypass の代表的パターン
パターン1:Referer 欠落許容
危険な実装例
if not referer or referer.startswith("https://bank.example"):
allow()
Referer が無い=OK
→ 攻撃者は「消すだけ」で突破。
パターン2:部分一致チェック
if "bank.example" in referer:
allow()
攻撃例:
https://bank.example.evil.com/
ドメイン一致していないのに通る
パターン3:サブドメイン悪用
Referer: https://blog.bank.example
-
blog.bank.exampleが攻撃者管理 - Referer チェック通過
- 実質 CSRF
攻撃フロー(概念)
[被害者がログイン済み]
↓
[攻撃者サイトにアクセス]
↓
(meta referrer=no-referrer)
↓
[銀行サイトへ POST]
↓
[Referer 欠落]
↓
[サーバが許可]
ユーザー操作・JS・CORSは一切不要。
ブラウザの正規挙動のみで成立します。
なぜ Referer 単体防御は破綻するのか
| 観点 | 問題 |
|---|---|
| 信頼性 | クライアント依存 |
| 安定性 | 欠落が正常挙動 |
| 攻撃耐性 | HTML だけで回避可能 |
| 実装ミス | null 許可・部分一致が多発 |
「セキュリティ対策をしている気分」になるだけ
正しい防御設計
Referer は「補助情報」まで
使うなら:
- 厳密なオリジン比較
- 欠落時は拒否
- Origin ヘッダと併用
本当に必要な CSRF 対策
| 対策 | 重要度 |
|---|---|
| CSRF Token(Synchronizer Token) | ★★★★★ |
| SameSite Cookie | ★★★★☆ |
| Origin ヘッダ検証 | ★★★☆☆ |
| Referer | ★★☆☆☆ |
実務での黄金パターン
1. CSRF Token 検証
2. SameSite=Lax / Strict
3. Origin ヘッダ厳密チェック
4. Referer は補助 or ログ用途
まとめ
Referer ベース CSRF 対策は、
- 「古い」
- 「壊れやすい」
- 「誤実装されやすい」
という三拍子が揃っています。
もし今、
「Referer チェックがあるから CSRF は大丈夫」
と思っているなら、
それは一番危険な状態です。