うつろい EC のログイン画面 — エラーメッセージが「メールアドレスが登録されていません」と「パスワードが間違っています」で区別されている。一見親切な設計だが、これが攻撃者にユーザの存在を漏らす脆弱性。
実際の DB には4名の会員が登録されています。攻撃者は事前に集めたメールアドレス候補リストを使って、どれがうつろい EC の会員かを判定します。
うつろい EC のログイン画面 — エラーメッセージが「メールアドレスが登録されていません」と「パスワードが間違っています」で区別されている。一見親切な設計だが、これが攻撃者にユーザの存在を漏らす脆弱性。
実際の DB には4名の会員が登録されています。攻撃者は事前に集めたメールアドレス候補リストを使って、どれがうつろい EC の会員かを判定します。
下のメールアドレス候補から、うつろい EC の会員4名を特定してください。各候補をログインフォームで試し、エラーメッセージの違いを観察します。
候補をクリックすると上のフォームのメールアドレス欄に自動入力されます。「ログイン」を押してエラーメッセージを観察し、会員4名を特定してください。
// ログインエンドポイント
$user = User::findByEmail($_POST['email']);
if (!$user) {
return [
'status' => 'error',
'message' => 'そのメールアドレスは登録されていません' // ← 漏洩
];
}
if (!password_verify($_POST['password'], $user->password_hash)) {
return [
'status' => 'error',
'message' => 'パスワードが間違っています' // ← 漏洩(ユーザは存在することが確定)
];
}
return ['status' => 'success'];
2種類のエラーメッセージで「ユーザが存在するか」が判別できる。攻撃者は適当なパスワード(anypassword など)で全候補を試して、応答メッセージの違いから会員を絞り込む。
うつろい EC のログイン画面は2種類のエラーを返します:
パスワードは何でも構いません(どうせ知らないので適当でOK)。各候補メールアドレスを順にフォームに入れて、エラーメッセージの違いを記録します。「パスワードが間違っています」が出たメールアドレスが会員。
登録されている会員4名:
store_admin@example.commiharu.tachibana@example.comyuki.nomura@example.comkanae.morita@example.comこれら4件で「パスワードが間違っています」が表示されます。残り4件は「そのメールアドレスは登録されていません」が表示され、非会員と判明。
これで攻撃者は「ユーザ列挙」に成功。次のステップはこれら4件へのブルートフォース(よくあるパスワードを総当たり)やクレデンシャル・スタッフィング(他社で漏れた ID/パスワードを試す)になります。