定義
サーバが「ユーザーが与えたアドレスへ代わりにリクエストを送る」機能(画像プレビュー、リンクサムネイルなど)を作るとき、攻撃者がそのアドレスをサーバ内部用のアドレスに差し替えて、こっそり到達する攻撃を防ぐ方法だ。
まず用語を解くと:fetch はサーバがある URL へ HTTP リクエストを送って内容を取得すること、allowlist(許可リスト)は「このホストだけリクエストを許可」というホワイトリスト、スキーム(scheme) は URL の先頭にある http:・https:・file: のようなプロトコルの種類だ。
正確に言えば SSRF(Server-Side Request Forgery — サーバ側リクエスト偽造) は、攻撃者がサーバに 意図しない URL を fetch させる脆弱性だ。画像リサイズプロキシ、OG fetcher(リンク共有時のプレビュー用に対象ページのメタデータを取得するサーバ)、webhook relay(外部イベント通知を代わりに転送するサーバ)のように ?url= パラメータを受け取ってそのアドレスへリクエストするサーバのエンドポイントは、すべてこの危険にさらされる。
なぜ必要か
ブラウザ(クライアント)は外部から会社の内部網へ直接リクエストを送れないが、サーバは送れる。 サーバは内部ネットワーク・プライベート IP、そしてクラウドメタデータアドレス(クラウドが自分のインスタンスの認証情報・設定を応答してくれる特殊な内部アドレス、AWS の場合 169.254.169.254)にもアクセスできる。
だからクライアントが直接叩けないアドレスを サーバプロキシを経由して 叩けるように放置すると、攻撃者が内部データの流出・内部網のポートスキャンにサーバを道具として使える。「我々は公開の画像 URL だけ受け取る」という仮定だけではこれを防げない — 受け取った URL が本当にそうなのか検証しなければならない。
動作原理
- URL パース → スキームが
http:/https:か確認。 - Hostname allowlist — suffix マッチング(例:
.cdn.example.com、.storage.provider)または明示的な host リスト。 - 拒否時は 400 + 拒否された hostname を本文に含める(運用デバッグ)。
- (推奨)private IP・link-local・metadata IP の遮断、リダイレクトの hop ごとに host を再検証。
- 環境変数でデプロイ別の suffix を追加 — コード変更なしで新しい CDN ドメインを許可。
実務での適用
- 画像プロキシ:許可したストレージ/CDN の suffix だけ通し、fetch は 完全な presigned URL(署名を含む)で実行しつつ、キャッシュキーは pathname だけを使うように分離する。
- エラー応答:
{ error: "Host not allowed", host: "evil.example" }— allowlist の漏れを即座に確認。 - デプロイチェックリスト:新しい object storage ドメインを追加する際は env + allowlist を同時に更新。
トレードオフ
| 選択 | 利得 | コスト |
|---|---|---|
| Suffix allowlist | 運用が単純 | subdomain 回避パターンの設計が必要 |
| Denylist のみ | 導入が速い | 回避・リダイレクトに脆弱 |
| リダイレクト無効化 | 安全 | 一部の CDN 動作が壊れることがある |
使ってはいけない場合
- ユーザー任意の URL fetch を「便宜上」allowlist なしで許可する。
- 内部デバッグ用に allowlist を
*(すべてのホストを許可)に緩めたものを、そのまま本番に残す。
よくある間違い
- コードに host を追加したのに、古い本番ビルド(
next start)が起動していて反映されない — プロセスの開始時刻・コマンドを確認。 - presigned URL の 署名クエリ と host 検証 を混同 — host は allowlist、fetch URL は完全なもの。
evil.amazonaws.com.attacker.comのような suffix マッチングのバグ —host.endsWith('.amazonaws.com')ルールを検討。
関連概念
- presigned-url-direct-upload — クライアント直接アップロード vs サーバ fetch
- server-image-proxy-transcoding-cache — 画像プロキシでのガード適用