オープンリダイレクト おーぷんりだいれくと
簡単に言うとこんな感じ!
信頼できる会社のURLに見せかけて、実は悪いサイトへ飛ばす「偽の案内板」みたいな攻撃だよ。「〇〇銀行のサイトだ!」と思ってクリックしたら、まったく別の詐欺サイトに連れて行かれてしまうってこと!
オープンリダイレクトとは
オープンリダイレクト(Open Redirect)とは、Webサイトが持つ「別URLへ転送する機能」を悪用し、ユーザーを意図しない第三者のサイトへ誘導できてしまう脆弱性のことです。たとえばログイン後に「元のページへ戻す」ためにURLパラメータで転送先を受け取る仕組みがあると、そのパラメータを攻撃者が書き換えることで、悪意あるサイトへ自由に飛ばせるようになります。
攻撃として特に危険なのは、URLの先頭部分が正規ドメインに見えるという点です。たとえば https://trusted-bank.example.com/redirect?url=https://evil.example.com というURLは、パッと見ると「trusted-bank.example.com」という信頼できそうな銀行サイトに見えます。これを利用してフィッシング詐欺のメールに貼り付け、ユーザーを騙すのがオープンリダイレクトを使った典型的な攻撃手口です。
オープンリダイレクト自体は「情報を盗む」機能を直接持つわけではありませんが、フィッシング攻撃・認証トークンの窃取・マルウェア配布サイトへの誘導など、他の攻撃の「踏み台」として非常に多用されます。実務の場では「大した脆弱性じゃない」と軽視されがちですが、組み合わせ次第で深刻な被害につながります。
攻撃の仕組みと構造
攻撃の流れ
攻撃者
│
├─① 正規サイトのリダイレクト機能を発見
│ 例: https://shop.example.com/login?next=●●●
│
├─② URLパラメータを書き換えた「罠URL」を作成
│ 例: https://shop.example.com/login?next=https://evil.example.com/fake-login
│
├─③ フィッシングメール等でユーザーに送りつける
│ 「ご利用ありがとうございます。こちらからログインしてください」
│
└─④ ユーザーがクリック → shop.example.com を経由して evil.example.com へ飛ぶ
ユーザーは「正規サイトに行ったはず」と思い込んでいる
被害のパターン
| パターン | 具体例 | 深刻度 |
|---|---|---|
| フィッシング誘導 | 偽ログイン画面でID・パスワードを盗む | ★★★★☆ |
| OAuth・トークン窃取 | 認証後のリダイレクトを乗っ取りトークンを横取り | ★★★★★ |
| マルウェア配布 | 悪意あるファイルのダウンロードページへ誘導 | ★★★★☆ |
| ブランド毀損 | 信頼できるURLを踏み台に使われたことで企業イメージ低下 | ★★★☆☆ |
覚え方
「看板は本物、中身は偽物」
正規ドメインという”看板”を借りて、実際には全然別の場所へ連れて行く。道路の案内板の数字だけ書き換えたいたずらをイメージするとわかりやすいよ。
歴史と背景
- 1990年代後半〜2000年代前半:Webサイトがログイン後のリダイレクトや外部リンク追跡のためにURLパラメータを使うようになり始める
- 2004年頃:フィッシング詐欺の急増とともに、正規サイトのリダイレクト機能が踏み台として悪用されることが報告され始める
- 2007年:OWASPが主要なWebアプリケーション脆弱性のひとつとして「Unvalidated Redirects and Forwards」を正式に取り上げる
- 2010年代:OAuth 2.0の普及により、リダイレクトURIの検証不備がアクセストークン漏洩に直結するケースが増加。GoogleやFacebookなど大手でも事例が報告される
- 2013年:OWASP Top 10 2013に「A10: Unvalidated Redirects and Forwards」として掲載(2017年版では削除されたが、依然として重要な脆弱性として認識されている)
- 現在:バグバウンティ(脆弱性報告報奨制度)プログラムでも継続して報告が多い定番の脆弱性のひとつ
安全な実装との比較・対策
実際の脆弱なコード例と修正例
# ❌ 脆弱な実装(next パラメータをそのまま使う)
@app.route("/login")
def login():
next_url = request.args.get("next", "/dashboard")
# 認証処理 ...
return redirect(next_url) # 外部URLでも無条件に飛ばしてしまう!
# ✅ 安全な実装(自ドメインのみ許可)
from urllib.parse import urlparse
@app.route("/login")
def login():
next_url = request.args.get("next", "/dashboard")
parsed = urlparse(next_url)
# スキームもホストも空(= 相対パス)のみ許可
if parsed.scheme or parsed.netloc:
next_url = "/dashboard" # 外部URLは無視してデフォルトへ
# 認証処理 ...
return redirect(next_url)
OAuthとオープンリダイレクトの危険な組み合わせ
OAuth 2.0の認可フローでは、認証後に redirect_uri パラメータで指定したURLへアクセストークンが渡されます。このURIの検証が甘い場合、攻撃者は自分のサーバーをリダイレクト先に指定してトークンを盗める状態になります。これは単なるフィッシングより深刻で、アカウント乗っ取りに直結するため、OAuthを実装するシステムでは特に注意が必要です。
関連する規格・RFC
| 規格・RFC番号 | 内容 |
|---|---|
| OWASP Top 10 2013 A10 | Unvalidated Redirects and Forwards として掲載 |
| RFC 6749 | OAuth 2.0 の仕様。redirect_uri の検証要件を規定 |
| RFC 6819 | OAuth 2.0 脅威モデルとセキュリティの考慮事項。オープンリダイレクトの危険性に言及 |
| CWE-601 | URL Redirection to Untrusted Site(共通脆弱性列挙)として定義 |
関連用語
- フィッシング — 偽サイトに誘導してID・パスワードを盗み取る詐欺手法。オープンリダイレクトはその誘導に使われる
- OAuth — 第三者アプリに権限を委譲する認証フレームワーク。リダイレクトURIの検証不備と組み合わさると深刻な被害に
- クロスサイトスクリプティング(XSS) — Webアプリの別の代表的脆弱性。オープンリダイレクトと組み合わせて使われることもある
- 脆弱性診断 — システムのセキュリティ上の弱点を発見するための検査。オープンリダイレクトの発見にも有効
- バグバウンティ — 脆弱性を発見・報告した人に報奨金を支払う制度。オープンリダイレクトは報告件数の多い定番脆弱性