Session fixation occurs when an attacker can cause a victim to authenticate while using a session identifier the attacker already knows. If the application keeps that identifier after login, the attacker may reuse it to access the newly authenticated session.

The core defense is to change the session identifier whenever privilege changes.

Rotate at authentication boundaries

After credentials, passkeys, or another authentication factor succeeds, create a fresh unpredictable session identifier and retire the pre-authentication identifier. Apply the same principle after privilege elevation, impersonation boundaries, or other security-sensitive identity changes.

Do not merely update user_id inside the existing anonymous session record.

A safe sequence is:

validate authentication
-> generate fresh session identifier
-> copy only required non-sensitive state
-> bind authenticated identity to new session
-> invalidate old identifier
-> send new cookie

If a cart or locale must survive login, copy an explicit allowlist of values rather than cloning arbitrary session state.

Let the server own session identifiers

Do not accept a session ID from query parameters, form fields, or arbitrary client storage when the application uses cookie-based sessions. The server should generate identifiers with a cryptographically secure random source through a mature session library.

Never derive identifiers from usernames, timestamps, counters, or other predictable values.

Configure cookies defensively

For HTTPS applications, session cookies should normally use Secure and HttpOnly. Choose an appropriate SameSite policy based on legitimate cross-site flows, and keep Domain and Path scopes as narrow as practical.

Cookie attributes reduce several adjacent risks, but they do not replace identifier rotation.

Invalidate old server-side state

Rotation is incomplete if both old and new identifiers remain valid. In server-side session stores, delete or revoke the old record atomically with the transition where possible.

For distributed systems, consider what happens if replicas observe revocation at different times. Authentication state needs consistency appropriate to the threat model.

Common pitfalls

Rotating only at logout

The dangerous transition is anonymous to authenticated. Rotate immediately after successful authentication, not just when a session ends.

Preserving every anonymous attribute

Untrusted pre-login state can become privileged after authentication. Copy only fields the authenticated workflow actually needs.

Logging raw session IDs

Session identifiers are bearer secrets. Avoid recording them in application logs, analytics events, traces, or error reports.

Confusing fixation with hijacking

Fixation arranges for the victim to use an attacker-known identifier before authentication. Hijacking steals or obtains an already authenticated identifier. Rotation addresses fixation; transport security, cookie controls, XSS defenses, expiration, and revocation help address broader session theft.

Test the transition explicitly

An integration test can begin with an anonymous session, authenticate, and assert that the resulting identifier differs and the old identifier no longer grants authenticated access. This is more useful than checking only that login succeeds.

Session security depends on lifecycle, not just randomness. Rotate identifiers when trust changes, invalidate previous state, and keep bearer values out of places where attackers or logs can capture them.