質問
掲示板などのユーザが直接入力できるURLリンクに設定する以外に成立する、オープンリダイレクト攻撃はありますか? |
解答
良い問いです — 「オープンリダイレクト」は単に掲示板の投稿欄に自由に URL を入れられるケースだけに限らず、さまざまな入力経路や実装上の癖を通じて成立します。 ここでは攻撃ベクトルのパターン(悪用の仕方を詳細手順で示すのではなく、発生箇所の理解と検出・対策に役立つ観点で)と、現場ですぐ使える防御策チェックリストをまとめます。 1) よくある(掲示板以外の)オープンリダイレクト経路 a. クエリパラメータ経由の `redirect`, `next`, `return_to` 等 ログイン後リダイレクト先やサインアウト後の遷移先をユーザ入力や外部リンクの `?next=` で受け取る実装。 検証が不十分だと外部へ飛ばせる。 b. URL短縮サービス / 中継サービス 短縮サービスや中間リダイレクトを行うサービス自体が外部 URL を受け取り、中継する場合。 これが乗っ取られると「信頼できるドメイン → 外部」経路を作れる。 c. OAuth / SSO の `redirect_uri` / `state` の不備 OAuth 登録済みリダイレクト URI を緩く扱ったり、`state` を検証しないと、認可コードやトークン流用に利用される危険性が高い(open-redirect がフックになり得る)。 d. HTTP ヘッダやホストに依存したリダイレクト `Location` を `Host` や `X-Forwarded-Host`、`Referer`、あるいはユーザ提供の `Host` ヘッダを基に生成する実装。 プロキシや CDN 経路を悪用されると任意リダイレクトを誘発する。 e. Cookie / セッションの `return` 値(POST/GET に埋められる) 「ログイン前に見ていたページへ戻す」ために cookie や隠しフォームフィールドで保存している遷移先を信頼して使う実装。 f. HTML の ` `、`window.location` を書くテンプレート サーバがユーザ入力を HTML テンプレートに埋め込み、それでクライアント側リダイレクトを行う場合。 XSS と組み合わさると悪用される。 g. URL 生成ロジックの不注意(相対パスの解釈ミス) `/goto?url=/path` のように相対パスだけ許すつもりが、`//evil.example` のようなスキーム相対 URL を受け入れてしまうパターンなど。 h. 外部コンテンツでの「安全そうな中継」 メールやPDF内のリンクが内部の短縮・中継サービスを経由するケース。 中継先が検証甘いとフィッシング誘導に使われる。 2) オープンリダイレクトが引き起こす代表的な問題点 * フィッシング誘導:信頼ドメイン → 外部に飛ばすことで誘導の信頼性を上げる。 * 認可/認証トークンの横取り補助:OAuth 等と組み合わさると認可コードのリプレイやトークンを奪う経路になる。 * CSRF / ログアウト回避の補助:ログアウトやワンタイム処理の回避に悪用されることがある。 * CSP 回避や混合コンテンツ誘発:外部リダイレクトでポリシー境界を壊す補助になることがある。 (※攻撃手順の具体的な詳細はここでは省きます) 3) 検出しやすいコーディングパターン(脆弱箇所の例) * `res.redirect(req.query.next)` のように ユーザ入力をそのまま Location に使う * 外部 URL チェックで「スキーム部分だけ確認」しているが、`//domain`(スキーム相対)を見落とす * ループバック・内部ホストをホワイトリスト化していない(`localhost` や社内ドメインの誤許可) * OAuth の `redirect_uri` をワイルドカードや部分一致で登録している 4) 実務で有効な防御策(優先順のチェックリスト) 1. 許可リスト(allowlist)方式を採用 * リダイレクト先は事前に登録されたホワイトリストのみ受け付ける。 ワイルドカードや部分一致は避ける。 2. 相対パスのみ許可する方針にする * `next=/dashboard` は OK、`next=https://evil` は NG。 絶対 URL を禁止するのが単純で有効。 3. 正規化と検証 * URL を受け取る前に正規化(IDN, エンコード、スキーム相対 `//` の検出)してから検証する。 4. 短縮サービス/中継は最小化・ログを出す * 中継サービスを使う場合は、生成時に認証付きトークンを持たせたり TTL を短くする。 運用ログを必ず残す。 5. OAuth / SSO は exact match を要求 * `redirect_uri` は完全一致で登録・検証する。 `state` を必ず検証する。 6. Host / X-Forwarded-Host を直接信頼しない * これらから Location を組み立てる実装は避ける、逆にプロキシやロードバランサの信頼チェーンが厳格であることを確認する。 7. ユーザ提示時に警告ページを挟む(内部ポリシー向け) * 外部へ遷移する必要がある場合は「あなたは今外部サイトへ移動します(リンク先を表示)」の中継ページを挟む。 8. 最小限の情報露出 * リダイレクト先にセッション ID やトークンを埋めない。 認証情報は URL に置かない。 9. 監査と自動検出 * アプリケーションスキャナ、SAST で `redirect` や `Location` を生成するコードを検出。 動的スキャンで外部飛びをテスト。 10. ユーザ入力を HTML に直書きしてクライアント側 JS で location 書き換えするのは危険 * XSS と組み合わさると大きなリスク。 サニタイズと CSP を併用。 5) 実装上の注意点(落とし穴) * 正規表現で「^https?://example.com」だけをチェックしていても、サブドメインや IDN(xn--)で騙される例がある。 * `//example.com`(スキーム相対)を許可してしまうと、HTTPS ページから HTTP 経由で外部へ誘導される恐れがある。 * ワイルドカード(`*.example.com`)は便利だが、サブドメイン乗っ取りリスクを招く。 6) 運用面の対策 * 重要なページ(ログイン・支払い)のリダイレクト処理はコードレビューとセキュリティレビューの対象にする。 * 外部遷移が発生したイベントは監査ログに残し、異常なリダイレクトの発生を検知するアラートルールを作る。 * サードパーティ統合(短縮サービスや SSO)を使う場合はできるだけ vendor のセキュリティ要件を確認する。 7) まとめ(短く) * オープンリダイレクトは 「どこからでも」発生しうる:クエリパラメータ、ヘッダ、短縮中継、OAuth 設定、クッキーなど。 * 防止の王道は 「ホワイトリスト化(事前登録)」+「絶対 URL 禁止(または厳格検証)」。 * 実装の小さな甘さ(スキーム相対、X-Forwarded-Host 信頼、ワイルドカード)で脆弱になるので、コーディング・運用で注意を払うこと |
|
この記事へのコメント