URLの先頭は本物のドメインなのに、開くと全く違うサイトへ転送されてしまう脆弱性が、オープンリダイレクトです。仕組みと確実な防ぎ方を解説します(攻撃手順は載せません)。
なぜ危険か
危険の本質は「ドメインへの信頼を悪用される」点です。
| 悪用のされ方 | 何が起きる |
|---|---|
| フィッシングの踏み台 | リンク先頭が本物ドメイン→利用者もフィルタも信用→偽サイトへ誘導 |
| 認証フローの横取り | OAuth等のリダイレクト先を細工し、トークン/コードの受け渡しを狙う |
| 他の脆弱性の増幅 | SSRF や XSS と組み合わせて被害を拡大 |
なぜ成立するか(仕組み)
「ログイン後に元のページへ戻す」などの機能で、戻り先URLをそのまま信じて転送すると起こります。利用者が見るURLの“先頭”は本物のドメインなので、最後まで疑いにくいのが厄介です。
防御:外部URLを受け取らない
遷移先は相対パスだけ許可(最重要)
戻り先は /dashboard のような相対パスのみ受け付け、フルURL(http://・// 始まり)は拒否。利用者が遷移先ドメインを指定できる余地を作らない。
許可リストに照合する
動的な遷移先が要るなら、既知の遷移先の固定セット(マップ)に対してだけ許可。一致しなければ既定ページへ。
文字列判定に頼らない
//evil・バックスラッシュ・@・多重エンコード等の回避が多い。受け取る設計を変える(相対+許可リスト)方が、フィルタ追記より確実。
どうしても外部へ飛ばすなら明示する
外部遷移が仕様なら、確認ページを挟んで「外部サイトへ移動します」と利用者に見せる。黙って飛ばさない。
当サイトの視点:単体では“低”でも、フィッシングと組むと効く
オープンリダイレクトは単体だと深刻度を低く見られがちですが、本物のドメインへの信頼を攻撃者に利用されるため、フィッシングや認証横取りと組み合わさると被害が大きくなります。だからこそ「相対パス+許可リスト」という設計レベルの対策で原因をなくすのが効率的です。SSRF(サーバーを任意先に通信させる)と発想が似ており、どちらも「遷移先・接続先を利用者に決めさせない」が共通の防御原則です。
オープンリダイレクト・SSRF・フィッシングの違い
オープンリダイレクトは、それ自体が攻撃というより、他の攻撃を信じさせやすくする欠陥です。関係の近い用語と並べると位置づけが分かります。
| 用語 | 何が起きるか | 誰が対策するか |
|---|---|---|
| オープンリダイレクト | 本物のサイトのURLから、利用者のブラウザが外部サイトへ転送される | 転送する機能を持つサイトの開発者 |
| SSRF | 指定された宛先へ、ブラウザではなくサーバーがリクエストを送る | URLを取りに行く機能を持つサイトの開発者 |
| フィッシング | 偽サイトで、ID・パスワードやカード情報を入力させる | 利用者・メールの受信側・なりすまされた組織 |
フィッシングのリンクに本物のドメインが使えると、利用者もメールのフィルタも見抜きにくくなります。オープンリダイレクトをなくすことは、自分のドメインを詐欺に使わせないための対策です。
具体例:ログイン連携(OAuth)での扱い
オープンリダイレクトが特に問題になるのは、ログイン連携(OAuth)です。認可の後、利用者は認可コードやトークンを持ったまま、登録されたリダイレクトURIへ戻されます。その戻り先のサイトにオープンリダイレクトがあると、コードやトークンが外部サイトへ送られるおそれがあります。
このため、OAuth 2.0のセキュリティのベストプラクティス(RFC 9700、2025年1月)は次の2点を求めています。
- 認可サーバーは、リダイレクトURIを事前登録したものと完全一致で照合する
- クライアントも認可サーバーも、クエリパラメータで受け取った任意のURLへ転送するページを置かない
オープンリダイレクトは CWE-601 として分類されています。単体で深刻度が高く評価されることは多くありませんが、ログイン連携の近くにあると重大な問題になります。
深刻度の目安
オープンリダイレクトは、単体では中程度と評価されることが一般的です。よく見られる評価の一例は、CVSS 3.1 で 6.1 です。
- 利用者がリンクを開く必要がある(UI:R)
- 影響は別サイトへの誘導にとどまり、サイトのデータを直接読めるわけではない
- ただし影響が転送元のサイトの外へ及ぶため、スコープ変更(S:C)として扱われる
点数だけで後回しにしないでください。ログイン連携の戻り先にある場合や、フィッシングの踏み台として実際に使われている場合は、優先して直します。自分の条件で点数を確かめたいときは CVSS計算ツールを使えます。
フレームワークに用意された安全な機能
自分で文字列を判定するより、フレームワークの機能を使う方が漏れが出にくくなります。代表的なものを挙げます。
| フレームワーク | 用意されている機能 | 内容 |
|---|---|---|
| Ruby on Rails | redirect_to の既定動作と url_from | 既定では別ホストへの転送を防ぐ。外部へ転送するには allow_other_host: true の明示が要る。url_from は同じホストのURLだけを返し、それ以外は nil を返す |
| ASP.NET Core | LocalRedirect と Url.IsLocalUrl | 同じサイト内のURLだけに転送し、外部URLなら例外にする |
Railsの公式ドキュメントは、allow_other_host: true を使う場合でも、利用者から受け取ったパラメータをそのまま渡すのは安全でないと注意しています。外部へ転送する機能を足すときは、この組み合わせを避けます。
自分のサイトで確認する方法
転送先を受け取るパラメータを探す
ソースコードとURLの一覧で、next・url・redirect・return_to・continue・callback のような名前のパラメータを探し、それをそのまま転送処理に渡していないかを確認する。
照合の方法を確認する
転送先を検証している箇所が、文字列の前方一致や「http で始まるか」の判定になっていないかを見る。URLの解析器でスキーム・ホスト・ポートに分けてから許可リストと照合するか、フレームワークの安全な関数(ASP.NET Core の LocalRedirect など)を使う。
ログイン連携の登録内容を見る
OAuthやSSOの設定画面で、登録しているリダイレクトURIにワイルドカードや不要な古いURLが残っていないかを確認する。
IDで転送先を選ぶ形にできないか検討する
外部への転送が必要なら、URLそのものではなく短いIDを受け取り、サーバー側の対応表で転送先を決める形にする。OWASPもこの方法を勧めている。
アクセスログで外部への転送を探す
アクセスログで、転送先のパラメータに自分のドメイン以外のホスト名が入ったリクエストを探す。見つかった場合は、その転送処理が外部へ飛ばしていないかを確かめ、誰かがリンクを配っていないかの手がかりにする。
出典(一次情報)
- OWASP「Unvalidated Redirects and Forwards Cheat Sheet」 — cheatsheetseries.owasp.org(IDとサーバー側の対応表、解析したURLでの許可リスト照合、確認ページ)
- IETF RFC 9700「Best Current Practice for OAuth 2.0 Security」(2025年1月) — datatracker.ietf.org(リダイレクトURIの完全一致、オープンリダイレクタの禁止)
- Ruby on Rails API「ActionController::Redirecting」 — api.rubyonrails.org(別ホストへの転送の既定の防止、
allow_other_host、url_from) - Microsoft「Prevent open redirect attacks in ASP.NET Core」 — learn.microsoft.com(
LocalRedirect、IsLocalUrl、外部URLが来たときの記録) - MITRE「CWE-601: URL Redirection to Untrusted Site ('Open Redirect')」 — cwe.mitre.org