Hello there, ('ω')ノ
✅ なぜパスワード再設定が必要なのか?
多くのユーザはパスワードを忘れてしまうことがあるため、パスワード再設定機能はほぼすべてのWebサービスに存在します。
しかし、通常のログインができない状況下で本人確認を行う必要があるため、この機能自体がセキュリティ上非常にデリケートです。
⚠️ パスワード再設定機能は“本人確認なし”で危険なことが起きる
攻撃者にとって、パスワード再設定機能は次のような狙いどころになります:
- 他人のアカウントのパスワードを変更して乗っ取る
- 認証をスキップしてログイン状態に持ち込む
- 登録済みユーザの情報を推測・列挙する
❌ 脆弱な実装例①:メールでパスワードを送信
問題点:
- 本来、パスワードはサーバに平文で保存されていないはず。送信できるという時点で実装に問題。
- 仮に新しいパスワードを生成してメール送信しても、メール経路が暗号化されていない場合、盗聴される可能性がある。
- メールはスマホ・PC間で自動同期され、長期間保存されることが多く、安全ではない。
結論:
メールで直接パスワードを送る実装は、完全にNG。
✅ 一般的な実装:リセット用URLをメールで送信
多くのサイトでは、以下のような流れになっています:
- ユーザが「パスワードを忘れた」をクリック
- 登録済みメールアドレスを入力
- メールにリセット用のリンク(URL)が送信される
- リンクを開くと、パスワード再設定画面に遷移
- 新しいパスワードを設定
❌ 脆弱な実装例②:URLにユーザ名などの識別子を含む
http://vulnerable-website.com/reset-password?user=victim-user
問題点:
- 攻撃者が別のユーザ名に書き換えるだけで、そのユーザのパスワード再設定ができてしまう
- ユーザ列挙にも悪用される(存在しないユーザ名ではエラーになる等)
✅ 安全な実装例:ハイエントロピーなトークンを使う
http://vulnerable-website.com/reset-password?token=a0ba0d1cb3b63d13...
必須条件:
- トークンは予測不可能な乱数で生成(UUIDやSHA-256など)
- トークンはデータベース上でユーザIDと紐づけて管理
- トークンの有効期限を短く設定(例:30分以内)
- パスワード変更後にトークンを削除(無効化)
❌ 脆弱な実装例③:フォーム送信時にトークンの再検証をしない
どういうこと?
- 攻撃者が自分のアカウントでリセットリンクを受け取る
- トークン付きの再設定ページにアクセスする
- HTMLソースの
formやinputを書き換えて、他人のユーザ名を指定 - サーバ側でトークンとユーザの関係を再確認しなければ、他人のパスワードが変更できてしまう
結論:
- 表示だけでなく、送信時の処理にも必ずトークンとユーザの整合性チェックが必要!
✅ 診断・実装時のチェックポイントまとめ
| チェック項目 | 説明 |
|---|---|
| パスワードがメールで送られていないか? | 送信内容を確認 |
| URLに予測可能なパラメータ(ユーザ名等)が含まれていないか? | クエリパラメータに注目 |
| トークンは十分にランダムか? | UUIDやハッシュなどを使用しているか確認 |
| トークンの有効期限は短いか? | 1時間未満が理想的 |
| トークンはパスワード変更後に無効化されるか? | 二度使用ができないか確認 |
| 送信時にもトークンとユーザの整合性チェックをしているか? | サーバサイドのロジックを確認または推測 |
🔚 まとめ
パスワード再設定機能は、アカウントを乗っ取るための強力な攻撃ポイントになり得ます。
だからこそ、次の3点を絶対に守る必要があります:
- トークンは強力にランダムかつ短命であること
- ユーザIDをURLに直接含めないこと
- トークンを常にサーバ側で検証すること(特に再設定時)
Best regards, (^^ゞ