今回はWeb Security Academyの「Password reset broken logic」ラボをもとに、パスワードリセット機能の設計ミスについて解説します。
パスワードリセットは、ほとんどのWebサービスにある便利な機能です。
しかし設計を間違えると、
- 他人のパスワードを勝手に変更できる
- メール認証をスキップできる
といった非常に危険な状態になります。
この記事ではこのラボをもとに、
- 何が起きるのか
- なぜ起きるのか
- WordPressサイトならどうなるのか
を初心者向けに整理します。
Password reset broken logicラボの概要
このラボでは、パスワードリセット機能にロジックの欠陥があります。
本来パスワードリセットは次の流れになります。
- ユーザーが「パスワードを忘れた」をクリック
- 登録メールにリセットリンクが送信される
- リンクに含まれるトークンを確認
- 新しいパスワードを設定
しかしこのサイトでは、リセットトークンの確認が行われていません。
その結果、任意のユーザーのパスワードを変更できてしまいます。
Password reset broken logicの攻撃の流れ
このラボでは次の手順で攻撃が成立します。
- 自分のアカウントでパスワードリセットを実行
- メールのリセットリンクを確認
- Burpでパスワード変更リクエストを確認
- リセットトークンを削除
- username を carlosに変更
- パスワードを変更
- Carlosのアカウントにログインできる
【攻撃の流れ】
パスワードリセット申請
↓
メールにリセットリンク送信
↓
新しいパスワード送信リクエスト
↓
トークン未検証
↓
別ユーザーのパスワード変更成功
この図のポイントは、メール認証のはずなのに、実際には確認していないという点です。
なぜパスワードリセットトークンが無視されるのか
この脆弱性の原因はとてもシンプルです。
トークンを検証していないという設計ミスです。
パスワードリセットでは通常、
- トークン
- ユーザー
- 有効期限
などをサーバー側でチェックします。
しかしこのサイトでは、POSTリクエストに含まれる username をそのまま信用しています。
つまり、
- リセットメール
- トークン
- 本人確認
これらが完全に意味を失っている状態です。
Password reset broken logicの意味
ラボ名の「Password reset broken logic」は次の意味です。
- Password reset:パスワードリセット機能
- broken logic:ロジック(設計)が壊れている
つまりこのラボは、「パスワードリセット機能の設計ミス」をテーマにしています。
なぜこれはビジネスロジック脆弱性なのか
この問題はSQLインジェクションやXSSのようなプログラムのバグではありません。
原因は、機能の設計ミスです。
システムとしては正常に動いています。
しかし、
- 誰のパスワードを変更するか
- トークンを確認するか
という業務ロジック(ビジネスロジック) が壊れています。
そのためこれは、ビジネスロジック脆弱性に分類されます。
WordPressサイトで起きた場合の具体例
WordPressでもパスワードリセット機能があります。
もし同じ設計ミスがあると、次のような状態になります。
【WordPressで起きる攻撃の流れ】
ユーザーが「パスワードを忘れた」をクリック
↓
リセットメール送信
↓
新しいパスワード設定フォーム
↓
usernameを書き換え
↓
他ユーザーのパスワード変更
この場合、攻撃者は、
- 管理者
- 編集者
- 会員サイトのユーザー
などのアカウントを乗っ取れます。
例えば会員サイトなら、
- 有料会員アカウント乗っ取り
- 管理者権限の奪取
- WooCommerce管理画面アクセス
などの被害につながります。
WordPressでの対策ポイント
WordPress本体はこのような設計にはなっていませんが、独自開発の機能やプラグインでは注意が必要です。
重要なポイントは次の通りです。
- トークンを必ず検証する
- トークンとユーザーを紐づける
- トークンの有効期限を設定する
- POSTのusernameを信用しない
特に危険なのは、「hidden input の username をそのまま使う設計」です。
これは多くの自作フォームで起きやすいミスです。
設計視点で見ると何が問題だったのか
このラボの本質は、認証の責任がどこにあるかという問題です。
本来、トークンの確認やユーザーの特定は、サーバー側が管理するべき情報です。
しかしこのサイトでは、クライアント(ブラウザ)の入力を信用しています。
その結果、ユーザーを書き換えるだけで他人のパスワード変更が可能になりました。
パスワードリセット機能の設計チェックリスト
パスワードリセット設計では、次の5点を必ず確認します。
- トークンはサーバー側で検証しているか
- トークンとユーザーが紐づいているか
- トークンの有効期限があるか
- username をリクエストから信用していないか
- トークンを使ったあと無効化されるか
パスワードリセット機能の診断チェックポイント
パスワードリセット機能を診断するときは、次を確認します。
- トークン無しでパスワード変更できないか
- username を変更すると別ユーザーに影響しないか
- トークンの有効期限があるか
- トークンが使い回せないか
このあたりをBurpで確認すると、ロジックミスが見つかることがあります。
まとめ|パスワードリセット機能の設計ミスは重大な脆弱性
Password reset broken logicは、パスワードリセット機能の設計ミスを扱うラボです。
この脆弱性があると、
- 他人のパスワード変更
- アカウント乗っ取り
- 管理者アクセス
など重大な被害につながります。
特に注意すべきポイントは、クライアントの入力を信用してしまう設計です。
パスワードリセットのような重要機能では、必ずサーバー側で本人確認を行うことが重要です。
よくある疑問
Q. パスワードリセットトークンとは何ですか?
メールに送られる 一時的な認証コードです。
本人確認のために使われます。
Q. トークンがなくても変更できることはありますか?
通常はありません。
もし可能なら重大な設計ミスです。
Q. WordPressでも起きますか?
WordPress本体では起きません。
ただし、自作機能やプラグインでは発生する可能性があります。
Q. なぜ username を変更できるのでしょうか?
多くのフォームでは、
<input type=”hidden” name=”username”>
のように送信されるためです。
サーバー側がこれを信用すると、攻撃が成立します。
