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 cookieIf 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.