Session Fixation and Cookie Flag Failures: A Practical Deep Dive
Session fixation is one of those bugs that reads as textbook-old yet still lands, because the fix — rotate the session ID at login — is easy to forget when auth is bolted onto a framework or split across services. The core question: if I hand a victim a session identifier before they log in, do I still know their session after they log in?
The mechanic in one paragraph
The app sets a session cookie for an anonymous visitor. The user authenticates. If the server keeps the same session ID and simply flips it to "logged in," then anyone who planted that ID earlier now shares the authenticated session. Fixation is really an authentication-boundary bug wearing a cookie costume.
Testing it with two browsers
You need a session you control and a victim you also control (your second account is fine to model the victim).
- In browser A, hit the site unauthenticated and capture the session cookie value — call it
S. - Force
Sinto browser B by any planting vector you can find (a URL parameter the app copies into the cookie, a subdomain cookie write, an XSS, or just manual injection to model the attack). - Log into the victim account in browser B.
- Back in browser A, still holding
S, refresh an authenticated page.
If browser A is now logged in as the victim, the ID never rotated. That's session fixation with account-takeover impact.
The realistic delivery vector matters for severity. If the only way to plant S is opening DevTools, triage will rate it low. If a query parameter, a Set-Cookie on a sibling subdomain, or a login flow that accepts a caller-supplied session sets it, you have a real chain.
Cookie flags, tested not guessed
While you're in there, check the session cookie's attributes on the authenticated response, not the login page:
Secure— missing means the cookie rides plaintext HTTP if the user ever hits anhttp://linkHttpOnly— missing means an XSS can read the session directlySameSite—Nonewithout a good reason widens CSRF surface;LaxorStrictnarrows itDomain— set too broadly (.example.com) shares the cookie with every subdomain, including that forgotten marketing host
Don't file "missing HttpOnly" as its own critical. On its own it's a hardening note. It becomes serious when you can chain it — an XSS that now trivially steals the session, or a mixed-content page that leaks a non-Secure cookie.
The other half: logout and rotation
Two related tests earn their keep. First, does the session survive logout? Capture the cookie, log out, replay the old cookie — if it still authenticates, server-side invalidation is broken. Second, does the ID rotate after a password change? A changed password that leaves old sessions valid means a victim who was compromised can't actually kick the attacker out.
Writing it up
Give the raw cookie values (redacted), the two-browser steps, the planting vector, and the before/after authenticated state. Tie severity to what the shared session can do — read messages, change email, move money. Recommend regenerating the session ID on every privilege change, invalidating server-side on logout and password reset, and setting Secure, HttpOnly, and an appropriate SameSite on the session cookie.
OWASP's Session Management Cheat Sheet is the reference for rotation, flags, and lifecycle — cite the specific rule your finding violates so triage can map it fast.