What is a session fixation attack and how is it prevented?
The attacker gives the victim a session ID before login, the victim logs in without the server changing the ID, and now the attacker — who knew the ID all along — is "logged in" as the victim.
Attack flow:
- Attacker visits
bank.com, gets a session cookiesid=XYZ. - Attacker tricks victim into using that same
sid=XYZ— by phishing a link with?sid=XYZ, or by setting the cookie via a subdomain XSS, or via a malicious script withdocument.cookie = "sid=XYZ". - Victim logs in. The server upgrades the session from anonymous to authenticated, but keeps the same ID.
- Attacker, who has
sid=XYZin their own browser, refreshes the page — and is now logged in as the victim.
The fix is one-line, and it's the only fix:
Always issue a new session ID after every authentication step (login, step-up auth, privilege change). Invalidate the old one server-side.
That makes the attacker's pre-shared ID worthless the moment the victim logs in.
This is an OWASP A2 — Broken Authentication issue. Both Java's HttpSession (request.changeSessionId()), .NET, PHP (session_regenerate_id(true)), Django, and Rails all expose a method to do this — using it is one line of code that prevents the whole class of attack.
Tip: "Session fixation" and "session hijacking" sound similar but are opposites. Fixation = attacker gives the victim a session ID. Hijacking = attacker steals one the victim already has.