こんにちは。現場の最前線で泥臭いインシデント対応に明け暮れているセキュリティエンジニアです。
今日は、多くの開発者が「なんとなく動いているから大丈夫だろう」と見過ごしがちな、OAuth 2.0のリダイレクトURIの落とし穴についてお話しします。
ここを突破されると、ユーザーのログイン情報や秘密のトークンが、いとも簡単に攻撃者の手に渡ってしまいます。「玄関の鍵をかけたはずなのに、実は裏口のドアが少し開いていた」……そんな状況を一緒に防いでいきましょう。
—
1. OAuthのリダイレクトURIって、そもそも何?
OAuth 2.0は、例えば「このサイトでGoogleログインを使う」といった時に使われる仕組みです。
あなたがGoogleでログインボタンを押すと、Googleのサイトに飛びますよね。認証が終わった後、Googleはあなたのブラウザを「元のサイト」に戻します。この「戻るべき場所」を指示する住所が、リダイレクトURIです。
泥棒の視点で考えてみよう
家(あなたのWebアプリ)に帰ろうとしている住人(ユーザー)に対して、泥棒が「こっちがあなたの家だよ」と偽の地図を見せて、自分のアジト(攻撃者のサーバー)へ誘導する……これがオープンリダイレクタ脆弱性です。
もし、この「戻る住所」を悪意のあるURLに書き換えられたら? あなたのアプリが発行した大切な「通行証(アクセストークン)」が、そのまま泥棒のサーバーに送信されてしまうのです。
—
2. なぜ「厳密な検証」が必要なのか?
多くの開発者は、リダイレクトURIを「なんとなく適当な文字列」でチェックしがちです。
- ❌ ダメな例:
https://example.com/callbackを許可したいのに、正規表現でhttps://.\.example\.com/.のように甘く設定する。 - ⭕ 正しい例:
https://example.com/callbackという一字一句違わない文字列だけを許可する。
なぜ厳密さが必要か。それは、少しでも隙があると「サブドメイン」や「パスの操作」で攻撃者が入り込むからです。例えば、https://example.com.attacker.com のようなURLを作られると、正規表現が甘いと「お、example.comが含まれているからOKだな!」と誤判定してしまいます。
—
3. ホワイトリスト方式で「玄関の鍵」をかける
実装の際は、「あらかじめ許可リスト(ホワイトリスト)に登録されたURL以外は、何があっても受け付けない」という姿勢を貫いてください。
実装コードの例(Node.js / Express風)
現場でそのまま使える、厳密なチェックのロジックです。
// 許可されたリダイレクト先のリスト(データベースや設定ファイルで管理)
const ALLOWED_REDIRECT_URIS = [
‘https://myapp.com/auth/callback’,
‘https://myapp.com/settings/callback’
];
function validateRedirectUri(requestedUri) {
// 1. 完全一致で判定する(これが鉄則!)
// 部分一致や正規表現での判定は極力避ける
if (ALLOWED_REDIRECT_URIS.includes(requestedUri)) {
return true;
}
// 2. 判定に失敗したらログに残して即座に遮断する
console.error([セキュリティ警告] 不正なリダイレクト先が要求されました: ${requestedUri});
return false;
}
—
4. 現場で守るべき「3つの鉄則」
コードを書くとき、以下のチェックリストを心の中で唱えてみてください。
1. ワイルドカードは絶対に使わない: .example.com のような設定は、攻撃者にとっての「フリーパス」です。
2. クエリパラメータにURLを含めない: 「ログイン後にどこへ飛ぶか」をパラメータで渡す設計(例: ?redirect_to=https://attacker.com)は、オープンリダイレクタの温床です。どうしても必要な場合は、アプリ内で定義した「ID」を使い、URLそのものをパラメータで渡さないようにしましょう。
3. 「直帰」を徹底する: 認可が終わったら、寄り道せずに登録済みの静的なURLへ飛ばす。これが最も安全です。
—
最後に:セキュリティは「疑う」ことから始まる
「便利な機能」は、往々にして「危ない機能」と表裏一体です。開発者が「ユーザーが迷わないように、柔軟にリダイレクト先を変えられたらいいな」と親切心で実装した機能が、実は泥棒への招待状になっている……そんな場面を私は何度も見てきました。
「自分のアプリは、自分の許可した場所へしかユーザーを帰さない」
この強い意志を持って、ホワイトリストを厳格に管理してください。最初は面倒に感じるかもしれませんが、それが結果として、あなたのサービスとユーザーを守る一番の近道になります。
一歩ずつ、セキュアな開発を積み重ねていきましょう!また何かあれば、いつでも相談してくださいね。
コメント