【パスワード再設定の罠】リセットリンクから乗っ取る手口と対策|CTF思考フレームワーク #03
こんにちは、アンペンです!
前回は、新規登録フォームで「すでに登録されています」と表示することで、第三者に会員であることが知られてしまう仕組みを見ました。
今回は、パスワードを忘れた人を助ける機能、パスワード再設定フォームを見ていきます。

パスワード再設定って、本人を助けるための機能だよね。攻撃に使われるってどういうこと?

「本人に届くはずの再設定用リンク」が、設計によっては本人以外でも使えてしまうことがあるんだ。
「パスワードを忘れた」ときのあの画面、誰でも一度は使ったことがありますよね。今日はあの何気ない画面を、“攻撃者の目”と“守る人の目”の両方からのぞいてみます。仕組みが分かると、ふだん使っているサービスが安全に作られているかどうかも、なんとなく見分けられるようになりますよ。
パスワード再設定は、メッセージの違いで会員かどうかが推測できるだけでなく、再設定用リンクの作り方が弱いとアカウント乗っ取りの入口になります。
この記事で分かること
- パスワード再設定フォームで、何を画面が教えているか
- 再設定用リンク(トークン)が狙われる典型的なパターン
- 演習環境での確認手順と、守る側の基本対策
📖 はじめてのWebセキュリティ #03|パスワード再設定編
本人を助けるための機能が、設計次第で情報漏れや乗っ取りの入口になる理由を、画面の見え方から考えていきます。 シリーズ一覧を見る →
⚠️ 大事なお約束
この記事の確認は、CTF・公式ラボ・自分で作った検証環境だけで行ってください。実在するサービスの再設定機能で、他人のメールアドレスやIDを試すことは絶対にしないでください。
パスワード再設定は「助ける機能」だからこそ手がかりになる
パスワード再設定フォームは、パスワードを忘れた利用者が、メールアドレスを入力して再設定用のメールを受け取る画面です。
本人にとっては、「登録されていないメールアドレスです」と表示されれば、入力ミスに気づける親切な機能に見えます。
でも、その親切な表示は、#01のログイン画面・#02の登録フォームと同じパターンで、第三者に会員であることを知らせる手がかりになってしまいます。
ちょっと意外かもしれませんが、『パスワードを忘れた人を助ける』という一番やさしい機能こそ、実は一番おしゃべりになりやすい場所なんです。というのも、ここを使うのは“ログインできない人=手元にメールアドレスしかない人”が前提。だからシステムはつい親切心で「そのアドレスは登録されていますよ/いませんよ」と教えたくなります。ところがその一言は、第三者にとってはそのまま会員名簿をチェックできる窓口になってしまうわけです。
図解:再設定リクエストの返事を比べてみよう


あれ、これって#02の登録フォームとそっくりだね。

そう。アカウントを扱う画面は、どこでも「便利な表示」と「漏れる情報」のバランスを考える必要があるんだ。
もちろん、登録の有無を隠すだけでこの機能が安全になるわけではありません。パスワード再設定には、ほかの画面にはない“もう一つの特徴”があります。それが、本人のメールに届く「再設定用リンク」の存在です。ここが甘いと、今度は情報漏れどころか、アカウントそのものを乗っ取られる入口になりかねません。順番に見ていきましょう。
もう一つの問題:再設定用リンクが「弱い」とどうなるか
パスワード再設定が他の画面と違うのは、本人に再設定用リンクがメールで送られてくることです。
このリンクには、本人だけが使えるはずの「鍵」のような文字列(トークン)が付いています。

あなたが鍵をなくしたとき、管理人が新しいスペアキーを作って郵送してくれるとします。もし、その鍵が「123」のような単純な番号でできていたらどうでしょう。誰かが順番に番号を試せば、あなたの部屋にも入れてしまいます。再設定リンクのトークンも、これと同じ役割なのです。
ここで覚える用語:リセットトークン
パスワード再設定のために、本人宛のメールに含まれる長い文字列のことです。URLの末尾に ?token=... のような形で付くことが多く、本人確認の代わりに使われます。
ここで『トークンって結局なに?』と身構えなくて大丈夫です。要するに“その人専用の、一回かぎりの合言葉”だと思ってください。宅配ボックスに届く一時的な開錠番号をイメージすると近いかもしれません。その番号が短かったり、誰の分も同じ規則で作られていたりすると、関係ない人でも当てて開けられてしまいますよね。再設定リンクのトークンが弱い、というのは、まさにこれと同じ状況なんです。
弱いトークンの代表的なパターン

- 短すぎる:6桁の数字だけなど、順番に試せば当てられる長さ
- 規則的:連番、時刻ベース、ユーザーIDの組み合わせなど、推測できる作り
- 使い回せる:一度使ったトークンが、その後も有効なまま残る
- 期限が長すぎる:1ヶ月以上有効など、忘れた頃にも使える設計
これらが組み合わさると、本人ではない第三者が、推測した別のメールアドレスのリセットを試して、たまたま有効なトークンを当てる、ということが起こり得ます。
ここがこの回のいちばん大事なところ。よく考えると、攻撃者はあなたのパスワードを知る必要すらないんです。『弱い鍵』を見つけて当てさえすれば、堂々と正面から再設定できてしまう。つまりパスワードをどれだけ複雑にしても、鍵の配り方が甘ければ意味がない、ということ。だからこそ守る側は、パスワードそのもの以上に“鍵の作り方”に神経を使います。では実際、その鍵はどんな形をしているのか。自分の演習環境でのぞいてみましょう。
CTFでやってみよう:再設定の流れを観察する
再設定リクエストの返事と、トークンの形を観察してみよう
目的は他人のアカウントを乗っ取ることではありません。「親切な機能から、外には何が見えているか」に気づくことです。
- CTFや自分の検証環境で、登録済みのテスト用アドレスを1つ用意する
- 未登録のテスト用アドレスを1つ用意する
- それぞれを再設定フォームに入力し、画面の返事を比べる
- 登録済みのアドレス宛に届いたメールから、再設定リンクのURLを確認する
- URLの中の
token=やcode=の値の長さ・文字種・規則性を観察する - 同じアドレスでもう一度再設定をリクエストし、新しいトークンの様子も比べる
記録してみよう
| 確認した項目 | 観察結果 | 気づいたこと |
|---|---|---|
| 登録済みアドレスへの画面の返事 | 自分で記録 | 自分で記録 |
| 未登録アドレスへの画面の返事 | 自分で記録 | 自分で記録 |
| トークンの長さ・文字種 | 自分で記録 | 自分で記録 |
| トークンの有効期限の表示 | 自分で記録 | 自分で記録 |
実際にトークンを眺めてみると、『これは長くてランダムだから安心そうだな』とか『これは短くて連番っぽいな…』と、強さの感覚がなんとなくつかめてきます。理屈より先に、この肌感覚を持てることが大きな一歩。では、守る側はどんな鍵を、どんなふうに配ればいいのか。具体的なポイントを整理しておきましょう。
守る側なら、メッセージを統一しトークンを強くしよう
パスワード再設定は、本人を助けつつ、第三者に手がかりを与えない設計にする必要があります。
そのために大切なのが、画面の表示とトークンの作り方の両方を整えることです。
- 画面では「入力されたメールアドレス宛に手順を送りました」のように、登録の有無を断定しない表示にする
- トークンは推測できない十分な長さ(目安として128ビット相当以上)の乱数で生成する
- 有効期限を短くする(目安として15分〜1時間程度)
- 一度使ったトークンは無効化し、使い回せないようにする
- 再設定が完了したら、本人へ完了通知メールを送る
- 再設定後は、それまでログイン中の他端末のセッションを無効化する
- 短時間に何度もリクエストされる場合は、速度制限や追加確認を組み合わせる

『128ビット相当の乱数』って急にむずかしい…それってどれくらいすごいの?

すごくざっくり言うと、“宇宙にある星の数よりずっと多い組み合わせ”くらいだよ。総当たりで当てようとしても、現実的な時間ではまず無理な桁なんだ。だから『長くてランダム』というだけで、それ自体が強力な守りになる。逆に6桁の数字だと100万通り——コンピュータには一瞬で当てられちゃうんだよ。
ここまでで『入口』の守りは見えてきました。でも実は、パスワードを変えた“後”にも落とし穴があります。せっかく鍵を新しくしても、古い鍵で開けっ放しのドアが残っていたら意味がない——そんな話です。
もう少し先の話:再設定後のセッションと「乗っ取り通知」
古いセッションが残っていると…
パスワードを変えても、攻撃者がすでにログイン状態のままだと意味がありません。再設定の完了時にすべてのセッションを切り直すことで、被害の継続を防げます。
本人への通知メール
「あなたのパスワードが変更されました」というメールを本人宛に送ると、心当たりがない再設定にいち早く気づけます。乗っ取られていた場合の被害を、本人の判断で早めに止められます。

「便利」と「安全」の境目を、設計のたびに考えるんだね。

そうそう。守る側に立つと、「画面のひと言」も「リンクのひとかけら」も全部、設計の対象になるんだ。
まとめ:再設定機能は「鍵の作り方」までセットで設計する
- 再設定リクエストの返事の違いから、登録の有無が推測される場合がある
- 再設定用リンク(トークン)が短い・規則的・期限が長いと、乗っ取りの入口になり得る
- CTFでは、画面の返事とトークンの形の両方を観察して、外から何が見えるかを確認する
- 守る側は、表示を統一し、トークンを長く・短命に・使い切りにし、再設定後のセッションも切る
今日いちばんの持ち帰りはシンプルです。『再設定は、鍵を作って・届けて・古い鍵を捨てるところまでで1セット』。このうちどれか一つでも雑になると、せっかくの親切機能が乗っ取りの近道に変わってしまいます。逆に言えば、この流れをていねいに設計できれば、利用者を助けながらしっかり守れる、ということ。便利と安全は、ちゃんと両立できるんです。
パスワード再設定は、ただ「パスワードを変える」だけの機能ではありません。鍵を作って届け、古い鍵を捨てるまでの一連の流れ全体を、安全に設計する必要があります。
次回は、誰もが毎日使う検索フォームを題材にします。「ただ検索するだけの入力欄」が、XSSやSQLiといった有名な攻撃の入口になる理由を、画面の見え方から見ていきましょう。
