今回は、PortSwiggerのWeb Security Academyにある 「Weak isolation on dual-use endpoint」 というラボをもとに、Webアプリの設計ミスによって他人のアカウントのパスワードを変更できてしまう脆弱性を解説します。
一見すると普通のパスワード変更機能ですが、内部の処理の設計に問題があると管理者アカウントまで乗っ取られる可能性があります。
WordPressサイトでも似たような設計をすると起き得る問題なので、初心者でも理解できるように整理していきます。
ラボの概要|パスワード変更機能のロジック欠陥
このラボでは、ログイン後に使えるパスワード変更機能に問題があります。
通常、パスワード変更では次のような確認が行われます。
- 現在のパスワード
- 新しいパスワード
- 確認用パスワード
しかしこのラボでは、現在のパスワードの確認が正しく行われていません。
そのため攻撃者は、管理者アカウントのパスワードを変更してログインできてしまいます。
最終的には、
- 管理者としてログイン
- 管理画面にアクセス
- ユーザー carlos を削除
することでラボが解決します。
攻撃の流れ|管理者アカウントを乗っ取る手順
このラボでは、Burp Suiteを使ってパスワード変更リクエストを改ざんします。
攻撃の手順は次の通りです。
- 自分のアカウントでログイン
- パスワード変更リクエストを確認
- current-password パラメータを削除
- username を administrator に変更
- 管理者パスワードを変更
- 管理者としてログイン
【攻撃の流れ】
ログイン
↓
パスワード変更リクエストを送信
↓
current-password を削除
↓
username を administrator に変更
↓
管理者パスワード変更成功
このラボでは、「誰のパスワードを変更するか」をユーザー入力に任せていることが問題になっています。
なぜ成立するのか|パスワード変更APIの設計ミス
この脆弱性の原因はシンプルです。
パスワード変更処理がユーザー入力を信用しているからです。
通常、パスワード変更は次の流れになります。
- ログイン状態を確認
- 現在のパスワードを確認
- 本人のアカウントだけ変更
しかしこのラボでは、
- username パラメータで対象ユーザーを指定
- current-password が無くても処理が通る
という状態になっています。
つまりサーバー側では、「ログインしているユーザー」と「変更するユーザー」の一致チェックが行われていません。
このような設計ミスがあると、他人のアカウントを操作できるようになります。
Weak isolation on dual-use endpointの意味を整理
「Weak isolation on dual-use endpoint」
少し分解すると意味が分かります。
Weak isolation:ユーザーごとの処理の分離が弱い
dual-use endpoint:複数の用途で使われるAPI
つまりこのラボは、「複数ユーザーの処理を同じAPIで扱った結果、ユーザー分離が壊れている」という脆弱性です。
なぜこれはビジネスロジック脆弱性なのか
この問題は、SQLインジェクションやXSSのような技術的なバグではありません。
原因は、アプリケーションの設計ミスです。
開発者は、次のように考えていた可能性があります。
ログインしているユーザーしかこの機能を使えない
しかし実際には、以下のチェックが不十分でした。
- 誰のパスワードを変更するか
- 本人確認がされているか
つまり、「処理の設計(ビジネスロジック)」に問題があるため、ビジネスロジック脆弱性に分類されます。
WordPressに置き換えるとどうなる?アカウント乗っ取りの例
では、この問題をWordPressに置き換えてみます。
例えば、次のような会員サイトを想像してください。
- 会員プロフィール編集ページ
- パスワード変更機能
- Ajax APIでパスワード変更
ここで次のような設計になっていたとします。
POST /api/change-passwordusername=admin
new-password=123456サーバーが「送られてきたusernameのパスワードを変更」という処理をしていると、攻撃者が管理者のパスワードを変更できてしまいます。
【WordPressで起きる場合の流れ】
ログイン
↓
プロフィール変更APIを確認
↓
usernameをadminに変更
↓
管理者パスワード変更
このような設計だと、サイト全体を乗っ取られる可能性があります。
特に次のようなケースで起きやすいです。
- 独自会員システム
- REST API
- Ajax処理
- プラグインのカスタム機能
WordPressサイトでの対策|パスワード変更機能の安全な設計
このような問題を防ぐには、サーバー側でユーザーを確定させる設計が重要です。
例えば次のような対策があります。
まず、パスワード変更対象のユーザーは、
- セッション情報
- ログインユーザーID
から取得します。
つまり、以下のようにする必要があります。
username = セッションのユーザー
さらに、
- 現在のパスワード確認
- nonce検証
- 権限チェック
なども重要です。
設計視点で見る問題点|ユーザー分離が壊れる理由
このラボの問題はユーザー分離の設計ミスです。
開発者は、「ログインユーザーしかこの機能を使えない」と考えていました。
しかし実際には操作対象のユーザーを入力値で決めていたため、攻撃者が自由に変更できてしまいました。
これはWebアプリ開発でよくあるミスです。
設計視点で整理する|脆弱性を防ぐチェックリスト
このラボの問題を設計視点で整理すると、次のポイントが重要になります。
- 操作対象のユーザーを入力値に任せていないか
- セッションユーザーと対象ユーザーが一致しているか
- パスワード変更時に現在パスワードを確認しているか
- 管理者アカウントを保護する仕組みがあるか
- APIで権限チェックをしているか
WordPress診断時のチェックポイント
WordPressサイトの診断では、次のポイントを確認すると良いです。
- REST APIでユーザー操作ができないか
- usernameパラメータが使われていないか
- パスワード変更APIが存在しないか
- nonceチェックがあるか
- 権限チェックがあるか
特にAjaxやREST APIの処理は見落とされやすい部分です。
まとめ|パスワード変更機能の設計ミスが生む脆弱性
Weak isolation on dual-use endpointは、ユーザーごとの処理の分離が弱いことで発生する脆弱性です。
今回のラボでは、
- パスワード変更API
- usernameパラメータ
- 現在パスワード未検証
という問題が組み合わさり、管理者アカウントが乗っ取られました。
WordPressでも、
- Ajax
- REST API
- プラグイン
などで同じ設計ミスが起きる可能性があります。
そのため、「ユーザーを入力値で決めない設計」がとても重要になります。
よくある疑問
Q. WordPress本体でこの問題は起きますか?
基本的にWordPressコアでは発生しません。
しかし独自開発のプラグインや会員サイトでは起きる可能性があります。
Q. WooCommerceでも起きますか?
WooCommerce本体では対策されています。
ただし、独自APIやカスタム機能では注意が必要です。
Q. なぜusernameを入力させる設計は危険なのですか?
ユーザー入力は攻撃者が自由に変更できるためです。
そのため重要な処理はサーバー側のセッション情報で決定する必要があります。
Q. REST APIは危険ですか?
REST API自体は安全です。
しかし 権限チェックを忘れると危険になります。
