Session ID not regenerated after login

Session ID not regenerated after login

Description

Reusing the existing session ID after a successful login may let an attacker turn an ID they fixed in advance into the victim’s authenticated session. Issue a new session ID before recording authentication state in the session.

Potential impact

  • Account compromise through session fixation
  • Reuse of a pre-authentication session ID for an authenticated session
  • Session misuse through shared browsers or links that lure users

Remediation

  • Regenerate the session ID immediately after authentication succeeds and check the result. The example’s session_regenerate_id(true) deletes the old session data. For concurrent requests or unstable connections, separately design the transition and restrictions on the old ID.
  • Store user IDs, roles and authentication flags in $_SESSION only after regeneration succeeds.
  • Delete session data and expire the session cookie on logout.

Examples

These excerpts run after a session has started and user authentication has succeeded. $user represents the authenticated user.

Before

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

After

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'];
    }
}

Explanation:

  • Before: Retains the existing ID after authentication, potentially promoting an attacker-fixed ID to the victim’s authenticated session.
  • After: Stores the authenticated user ID only after session ID regeneration succeeds.

References