コース目次 / 第3章
オープンリダイレクト — 行き先を確かめない穴
next パラメータをそのまま Location にする穴を突き、行き先を自サイト内に限る修正で塞いで、再検証します。
この章は攻撃をします(自作環境専用)。相手は自分のパソコンの shanai-memo だけです。行き先の例に使う evil.example.com は、ドキュメント用に予約された架空ドメインで、実在の第三者ではありません(法と倫理)。
オープンリダイレクトは、地味に見えて実害の大きい穴です。外から来た値をそのまま「次の行き先」にすると、攻撃者は自サイトのURLを入口にして、被害者を任意の外部サイト(偽ログイン画面など)へ運べます。URLの先頭が本物のドメインなので、利用者は信じてしまいます。
法と倫理ゲート
手を動かす前に
このコースは攻撃の技術に触れます。実習してよい相手は、次の3つだけです。
- (a) 自分で作った練習用のやられ環境(このサイトが配る自作ターゲット)
- (b) あなた自身の許可された環境(自分の Thousand SKY・secret-notes-ctf など)
- (c) CTF 競技の中(規約の範囲で)
実在する第三者のシステムを許可なく触ることは、不正アクセス禁止法に触れます。 このゲートは、その線引きを毎回の入口で確かめるためのものです。詳しくは「セキュリティの法と倫理」へ。
同意すると、この先の内容が表示されます。
穴のある場所を読む
shanai-memo には「ポータルへ戻る」ための /go があります。vulnerable/server.mjs の該当部分です。
if (pathname === '/go') {
const next = url.searchParams.get('next') || '/';
res.writeHead(302, { location: next }); // ← 行き先を確かめない(穴)
res.end();
}next に何が入っていても、そのまま Location にしています。/ のような自サイト内のパスならよいのですが、https://evil.example.com のような外部URLでも、素通しで飛ばします。
攻める
node exploit/open-redirect.mjs[OpenRedirect] 成立: 外部の https://evil.example.com/phish へリダイレクトしました(行き先を確かめていない)手で見るなら、curl -i でレスポンスヘッダを覗きます。
curl -s -i "http://127.0.0.1:4599/go?next=https://evil.example.com/phish"HTTP/1.1 302 Found
location: https://evil.example.com/phishhttp://127.0.0.1:4599/go?next=... という自サイトのURLを踏んだ人が、evil.example.com へ運ばれます。攻撃者はこの入口URLをメールなどで配り、飛んだ先に本物そっくりの偽ログイン画面を置きます。
直す
行き先を、自サイトの中(相対パス)に限るのが基本の直し方です。「先頭が1個の / で始まる」ものだけ許し、それ以外は安全な / に落とします。
if (pathname === '/go') {
const next = url.searchParams.get('next') || '/';
const safe = /^\/(?!\/)/.test(next) ? next : '/';
res.writeHead(302, { location: safe });
res.end();
}/^/(?!/)/ は「1個の / で始まり、2個目の / が続かない」を意味します。//evil.example.com のようなプロトコル相対URLは、ブラウザが外部サイトとして解釈するので、単純な「/ で始まる」判定では通ってしまいます。だから「2個目の / は許さない」まで書きます。外部への遷移をどうしても許すなら、行き先を許可リストで照合します。
再検証する
サーバを再起動して、もう一度攻めます。
node exploit/open-redirect.mjs[OpenRedirect] 防御されています: HTTP 302 / Location=/(外部へは飛ばない)外部URLを渡しても、行き先が自サイトの / に落とされました。
HTTP/1.1 302 Found
location: /持ち帰る一言
外から来た値で、行き先を決めない。 リダイレクト先・ファイルパス・SQLの識別子など、「外部入力がそのまま制御に使われる」場所はどこも同じ危うさを持ちます。行き先は自サイト内に限るか、許可リストで照合する——が既定です。
次章は、この3つの穴が実は同じ1つのことを言っていた、という締めくくりです。
こうなっていればOK
卒業まであと1章です。
この章はまだ完了していません。
保存できませんでした(プライベートブラウズ中かもしれません)。この端末に進捗は残りませんが、先へは進めます。