utsuroi auth labs 知識ベース 01 / 02 — 認証の基礎
Authentication Fundamentals · Knowledge Base
01

認証の基礎

Identification, authentication, authorization — and how each can break

認証(Authentication)とは「あなたが誰か」を確認する処理。これに対して認可(Authorization)は「あなたに何が許されるか」の判定。攻撃の多くは、この2つの境界が曖昧な実装の隙を突きます。

1. 識別と認証と認可 #identify-vs-auth

3つの異なる処理がしばしば混同される。

本カテゴリの Lab は主に識別と認証の段階の脆弱性を扱います。認可の脆弱性は Access Control Labs で別途扱います。

2. 3要素認証 #three-factors

「知っている」「持っている」「である」の3つ。

認証で使われる要素は大きく3カテゴリに分類されます:

複数の異なるカテゴリの要素を組み合わせるのが多要素認証(MFA)。同じカテゴリ内で2つ(パスワード + 秘密の質問)を組み合わせるのは多段階認証であって多要素認証ではないことに注意。

SMS による2要素認証の脆弱性

SMS は所持要素として広く使われていますが、SIM スワップ攻撃(攻撃者が通信会社に被害者を装って SIM 再発行を申請)で奪取される事例があります。重要なアカウントには TOTP アプリ(Google Authenticator 等)やハードウェアトークン(YubiKey 等)の方が推奨されます。

3. パスワードの保管 #password-storage

DB に平文で保存するのは20年前から論外。

パスワードを DB に保管する際は、遅いハッシュ関数を使った一方向ハッシュにすべきです。代表的な選択肢:

使ってはいけないもの:

// PHP — bcrypt
$hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);

// 検証時
if (password_verify($input, $hash)) {
    // 認証成功
}

ソルト(salt)は最近のライブラリ(password_hash 等)が自動的に付与・管理するので、明示的に扱う必要はほぼありません。

4. セッション管理 #session-management

認証後の状態保持。Cookie で識別子を保管するのが一般的。

HTTP は元々ステートレスなので、ログイン後の認証状態を保つ仕組みとしてセッションが使われます。

  1. ログイン成功時、サーバが暗号論的にランダムなセッション ID を生成
  2. サーバ側でセッション ID とユーザ情報を紐付けて保存(DB、Redis 等)
  3. レスポンスで Set-Cookie: session=xyz; HttpOnly; Secure; SameSite=Lax を返す
  4. 以降、ブラウザは自動的にこの Cookie を添付。サーバはセッション ID で「誰のリクエストか」を判定

セッション Cookie の重要属性:

セッション ID は十分なエントロピーを持つ必要があります(128bit 以上推奨)。連番や短い文字列だと総当たりで他ユーザのセッションを奪える。

5. ログインエラーメッセージの設計 #error-message

親切すぎるエラーメッセージは脆弱性。

ログイン失敗時のエラーメッセージで、よくある2つの設計を比較しましょう:

// 親切だが脆弱
if (user_not_found) {
    return "そのメールアドレスは登録されていません";
}
if (wrong_password) {
    return "パスワードが間違っています";
}
// 正しい設計
if (user_not_found || wrong_password) {
    return "メールアドレスまたはパスワードが正しくありません";
}

なぜ統一すべきか? 攻撃者が次のような試行をすれば:

  1. alice@example.com + 適当なパスワード → 「パスワードが間違っています」
  2. bob@example.com + 適当なパスワード → 「そのメールアドレスは登録されていません」

これだけで「alice@example.com は登録ユーザだが bob@example.com は登録されていない」という情報が漏れます。これをユーザ列挙(Username Enumeration)と呼びます。

なぜユーザ列挙が問題か

列挙されたメールアドレス一覧は、フィッシング、ブルートフォース、クレデンシャル・スタッフィング攻撃の入口になります。「このメールアドレスは うつろい EC の会員」という情報自体が、社会的に晒したくないプライバシーである場合もあります(成人向けサイト、医療系サービス等で特に深刻)。