utsuroi auth labs Lab 01 / 5 — Apprentice
01

Username Enumeration — ログインエラーメッセージから会員特定

Username enumeration via differential error messages

うつろい EC のログイン画面 — エラーメッセージが「メールアドレスが登録されていません」と「パスワードが間違っています」で区別されている。一見親切な設計だが、これが攻撃者にユーザの存在を漏らす脆弱性。

実際の DB には4名の会員が登録されています。攻撃者は事前に集めたメールアドレス候補リストを使って、どれがうつろい EC の会員かを判定します。

下のメールアドレス候補から、うつろい EC の会員4名を特定してください。各候補をログインフォームで試し、エラーメッセージの違いを観察します。

候補をクリックすると上のフォームのメールアドレス欄に自動入力されます。「ログイン」を押してエラーメッセージを観察し、会員4名を特定してください。

候補リスト(8件)
脆弱なサーバ実装(うつろい EC のログイン処理)
// ログインエンドポイント
$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 など)で全候補を試して、応答メッセージの違いから会員を絞り込む。

これまでの試行ログ
    ヒント 1 — エラーメッセージの種類

    うつろい EC のログイン画面は2種類のエラーを返します:

    • 「そのメールアドレスは登録されていません」 → ユーザ不在(=非会員)
    • 「パスワードが間違っています」 → ユーザは存在(=会員)、パスワードのみ違う
    ヒント 2 — 何を試せばいいか

    パスワードは何でも構いません(どうせ知らないので適当でOK)。各候補メールアドレスを順にフォームに入れて、エラーメッセージの違いを記録します。「パスワードが間違っています」が出たメールアドレスが会員。

    正解(ネタバレ)

    登録されている会員4名:

    • store_admin@example.com
    • miharu.tachibana@example.com
    • yuki.nomura@example.com
    • kanae.morita@example.com

    これら4件で「パスワードが間違っています」が表示されます。残り4件は「そのメールアドレスは登録されていません」が表示され、非会員と判明。

    これで攻撃者は「ユーザ列挙」に成功。次のステップはこれら4件へのブルートフォース(よくあるパスワードを総当たり)やクレデンシャル・スタッフィング(他社で漏れた ID/パスワードを試す)になります。