ログイン後に再発行されないセッションID

ログイン後に再発行されないセッションID

説明

ログイン成功後も既存のセッションIDを使うと、攻撃者が事前に固定したIDを被害者の認証済みセッションとして利用できるおそれがあります。認証状態をセッションへ記録する前に、新しいセッションIDを発行する必要があります。

想定される影響

  • セッション固定攻撃によるアカウントの乗っ取り
  • 認証前のセッションIDの、認証済みセッションへの再利用
  • 共有ブラウザーや誘導リンクを通じたセッションの悪用

対処方法

  • 認証成功直後にセッションIDを再発行し、成功を確認してください。例のsession_regenerate_id(true)は以前のセッションデータを削除します。同時リクエストや不安定な接続がある環境では、以前のIDへのアクセス制限と移行処理を別途設計してください。
  • 再発行に成功してから、ユーザーID、ロール、認証フラグを$_SESSIONへ保存してください。
  • ログアウト時はセッションデータを削除し、セッションCookieも失効させてください。

例

セッションを開始し、ユーザー認証に成功した後で実行する抜粋です。$userは認証済みユーザーの情報です。

変更前

php
<?php
class AuthController {
    public function login($user) {
        $_SESSION['user_id'] = $user['id'];
    }
}

変更後

php
<?php
class AuthController {
    public function login($user) {
        if (!session_regenerate_id(true)) {
            throw new RuntimeException('Session ID regeneration failed');
        }
        $_SESSION['user_id'] = $user['id'];
    }
}

説明:

  • 変更前: 認証後も既存のIDを使うため、攻撃者が事前に固定したIDを被害者の認証済みセッションとして利用できる可能性があります。
  • 変更後: セッションIDの再発行が成功してから、認証済みユーザーIDを保存します。

参考資料