【パスワード再設定の罠】リセットリンクから乗っ取る手口と対策|CTF思考フレームワーク #03
📖 この記事はシリーズの一部です
「CTF思考フレームワーク」 Webフォーム編 #03 / 公開中 7記事 → シリーズ一覧を見る →
「パスワードを忘れた」リンク、何気なく使ってますよね。でもここ、実はアカウント乗っ取りの黄金ルートとして攻撃者に大人気のフィーチャーです🔑
トークンの予測可能性、リダイレクト改ざん、HTTPホストヘッダー攻撃などが絡む🔬
パスワードリセットは「メール送信→トークン付きURLでリセット」という単純フローに見えて、攻撃面が想像以上に多いです。攻撃者の思考を追っていきましょう✨
👀 観察フェーズ:まず何を見る?

リセット機能って“裏口”になりやすいから、観察ポイント多めだよ。
リセット要求から完了までを一連の流れとして観察します。トークンの形式とURLのドメインが特に重要🔍
メールの生ソースをコピーして、リセットURLをBase64やJWTでデコードしてみるのおすすめ👀

トークンの形式って攻撃の鍵になるんだ…意識したことなかった💧
🤔 仮説フェーズ:攻撃者ならどう考える?

リセットは本人確認の代わりになる機能。だから狙われやすいんだ。
攻撃者は「トークンを盗む」「トークンを推測する」「トークンを迂回する」の3方向から狙ってきます。代表的な4つの仮説を見てみましょう。
🎯 仮説①:トークンが連番・タイムスタンプ=予測可能
連番やタイムスタンプ+ユーザーIDでトークンを生成していると、被害者がリセット要求した瞬間に数秒〜数分でトークンが推測されます。UUID v4や暗号学的に安全な乱数を使うべきです。

え、時刻+IDで作るとそんなに簡単にバレるの…!?
🪤 仮説②:HostヘッダーがリセットURLに使われる
メール本文のリセットURLがリクエストのHostヘッダーから組み立てられている場合、攻撃者がHost: attacker.comに改ざんすれば被害者宛メールに偽URLが届きます。クリックされた瞬間にトークン窃取。

えっ、メールに届くURLが攻撃者のドメインに書き換わるの…?怖すぎ💧
🔓 仮説③:リセット完了APIにIDORがある
パスワード変更APIにuserIdパラメータが露出していて、自分のトークンで通っちゃう実装だと、他人のパスワードを自由に書き換えられます。トークンとIDが紐づいていない致命的バグ。

うわ、userIdを変えるだけで他人のパスワード変えられるの…?致命的すぎる💧
⏰ 仮説④:トークンに有効期限がない/再利用できる
トークンに有効期限がない、または使い回し可能だと、メール窃盗・SSRF・履歴漏洩などで一度漏れたトークンがいつまでも有効に。15-60分の有効期限+使い切りが原則です。

昔のメールに残ってるリンクでいまだに侵入できるのか…ヤバい
リセット機能の4観点チェックは、ログイン画面と同じくらい重要。次は実際に検証する手順へ💡
🔬 検証フェーズ:実際に試す手順

リセットの検証はトークン形式と有効期限が中心になるよ。
仮説を実際に試して確認します。必ず自分の環境か、許可された環境で。
存在するメアドと存在しないメアドでリセット要求。レスポンスが同一かを確認。
届いたURLのトークン部分を3〜5回採取して比較。連番/タイムスタンプ/UUIDv1(時刻ベース)なら予測可能性あり。
一度使ったリセットURLをもう一度叩く。エラーにならなければ使い回し可能=大問題。
curlで Host: attacker.com を付けてリセット要求。届いたメールのリンクが attacker.com になっていれば脆弱。
PCとスマホ両方でログインしておき、PCでリセット。スマホ側のセッションが切れない=乗っ取り後も気づかれにくい。

うわ、トークンの長さや文字種を見ただけで生成方法が推測できちゃうの!?

そう。UUID v4で十分長く、毎回新しいもの。これが鉄則。
⚔️ 攻撃フェーズ:攻撃者ならこう攻める

“なぜ通るか”を理解するのがゴール。攻撃の流れが分かれば対策も見える。
検証で「ここ弱いな」と判断したら、実際の攻撃手法に移ります。リセット機能でよくある攻撃はこの3パターン。
タイムスタンプ+ユーザーIDなど予測可能な要素でトークン生成してると、被害者のリセット中の数秒〜数分間にトークンを推測してアカウント奪取💥
リセット要求時にHostヘッダーを攻撃者ドメインに改ざん。被害者宛メールに「https://attacker.com/reset?token=xxx」が届き、被害者がクリック→トークン窃取🪤
リセット完了APIに userId パラメータが露出している場合、自分のトークンで他人のパスワードを書き換えられる致命的バグ。

えっ、Hostヘッダーを書き換えるだけでメールのURLが攻撃者ドメインに…ホラーじゃん💧
結果として、こんな”フラグ”を取られちゃうイメージ:
POST /api/reset-password
{"token":"my-token","userId":42,"newPassword":"hacked"}
→ 200 OK
FLAG{idor_in_password_reset}パスワードリセットは「他人のアカウント奪取=完全乗っ取り」につながる最重要面。攻撃インパクト極大🚨
🛡️ 防御フェーズ:どう守る?

やっとお待ちかね、守る側の打ち手。攻撃を見たあとだとスッと入ってくるよ。
攻撃側を理解したら、守る側の打ち手も見えてきます。設計・実装・運用の3レイヤーで考えるのがコツ🛡️
- リセット要求は存在/不在問わず「メール送信しました」で統一
- トークンは暗号論的乱数(CSPRNG)で128bit以上
- リセットURLはサーバ設定の正規ドメインから生成(Hostヘッダー使わない)
- リセット完了で全セッション無効化+通知メール送信
- トークンは1回限り、有効期限15〜30分
- IPレート制限(同IPから/日 5回まで等)
- リセットAPIは認証済みユーザーのみで userId 受け付けない
- OTP(6桁コード)方式の場合は試行回数制限(5回程度)と短い有効期限(5〜10分)
- リセット要求の異常検知(短時間に大量、海外IP等)
- リセット完了通知は別経路(SMS等)併用も検討
- パスワード変更履歴をユーザーに見える化

なるほど…UUID + 短い有効期限 + 使い切りがリセットの基本セットなんだね!

その通り。トークン管理がリセット機能のキモだよ🛡️
🛡️ 今日からできる対策ツール
パスワードの使い回しや手動管理はどんなに気をつけても限界があります。🔑 パスワード管理ツール「ワンパス」なら、複雑なパスワードを安全に保管して「1つのマスターパスワード」だけ覚えられるので、今日から始める防御策としてしっくりきます。
※ 上記は他社サービスへのリンクです。購入は各自でご判断ください。
⚠️ よくある落とし穴
- トークンにユーザーIDをそのまま含めて、改ざんで他人のリセットができる
- メール送信が遅延し、「2回押したら2通来る=両方有効」状態になる
- リセットリンクがログ・Refererに残り、内部関係者から漏洩
🧰 ツール早見表
| ツール | 何ができる | 使いどころ |
|---|---|---|
| Burp Suite | リセット要求の改ざん | Hostヘッダー攻撃の検証 |
| CyberChef | トークンのデコード/解析 | JWTやBase64 |
| Hashcat | 弱いトークンの総当たり | 検証フェーズ(演習のみ) |
| jwt.io | JWTデコード/署名検証 | トークン解析 |
🎓 本気で学びたい人へ
Webセキュリティを「趣味」から「仕事」に変えたい方へ。🎓 ササエルはインフラエンジニアに特化したオンラインスクールで、セキュリティ設計の基礎から体系的に学べます。
📚 もっと深く学びたい人へ
体系的に攻撃と防御の両面を学びたいなら『ホワイトハッカー入門 第2版』が分かりやすい入口です📚
📚 次に読みたい
📰 関連の実例・ニュース解説
この攻撃が実際に使われた事件・対策ガイドはこちら:
CTF・セキュリティ学習ハブページへ


