What Is Session Fixation?
Session fixation tricks a victim into using an attacker-known session ID, so logging in hands the attacker an authenticated session too.
Session fixation is an attack where the attacker sets a victim’s session ID to a value the attacker already knows before the victim logs in, so that when the victim authenticates, the attacker’s pre-chosen session ID becomes a valid, authenticated session — one the attacker can use directly, without ever stealing a cookie or intercepting traffic. It exploits applications that accept a session ID from outside and keep using it across the login boundary, rather than issuing a fresh one at the moment of authentication.
How the attack plays out
The attack depends on an application that lets a session ID be set before login and doesn’t replace it afterward:
- The attacker visits the target site and either obtains a valid but unauthenticated session ID, or crafts one — some vulnerable applications accept an arbitrary session ID passed as a URL parameter or cookie value even before any session exists.
- The attacker gets the victim to use that specific session ID. This might mean sending a link containing the ID as a query parameter (
https://example.com/login?sessionid=ATTACKERKNOWN123), or, on sites that accept cookies set by any page on the domain, planting the cookie directly. - The victim, unaware anything is wrong, logs in normally through the legitimate site using that session ID.
- If the application doesn’t issue a new session ID at login, the session tied to
ATTACKERKNOWN123is now authenticated as the victim — and the attacker, who already knows that ID, can use it to access the account directly, no password or MFA required.
The victim never noticed anything unusual; the URL looked like the real site because it was the real site, just carrying a session identifier the attacker chose in advance.
Why this is different from session hijacking
Session fixation and session hijacking both end with an attacker holding a valid session, but they get there differently. Hijacking requires the attacker to steal an existing authenticated session ID — via XSS, packet sniffing on an unencrypted connection, or a leaked log. Fixation requires no theft at all: the attacker supplies the session ID up front and simply waits for the victim to authenticate under it. That makes fixation possible even against connections fully protected by HTTPS and applications immune to XSS, because the vulnerability isn’t in transport or script injection — it’s in how the application manages session identity across the login event itself.
The core defense: regenerate the session ID at login
The fix is narrow and specific: issue a brand-new session ID the moment a user authenticates, and invalidate whatever session ID existed before login. Nearly every modern web framework does this by default in its session-handling middleware — a fresh session ID on login is standard, unremarkable behavior in a properly configured app. The vulnerability shows up almost exclusively in custom session-handling code, older frameworks configured against their defaults, or systems that deliberately preserve a session across login for convenience (to keep a shopping cart, for instance) without regenerating the identifier while doing so.
This single change closes the attack completely: even if an attacker successfully fixes a victim’s pre-login session ID, that ID becomes worthless the instant the victim logs in, because the server discards it and issues one the attacker never saw.
Supporting defenses
A few related practices reduce the attack surface further, even though session regeneration is the actual fix:
- Never accept a session ID from a URL parameter. Sessions should live in cookies, ideally
HttpOnlyso client-side scripts can’t read or set them, andSameSite-restricted so a session ID can’t be planted via a cross-site request. See how cookie attributes likeHttpOnlyandSameSitework for the mechanics. - Reject externally supplied session IDs. If a request arrives with a cookie naming a session ID the server has never issued, the server should generate a new one rather than adopting the attacker-supplied value as if it were legitimate.
- Set a reasonably short session lifetime. This doesn’t prevent fixation but limits how long a fixed session stays exploitable if the regeneration defense is somehow missing.
Session fixation vs related identity attacks
| Session fixation | Session hijacking | CSRF | |
|---|---|---|---|
| Attacker needs to steal a token | No — supplies it in advance | Yes | No — rides an existing session |
| Point of compromise | Before login | Any time after login | During an authenticated action |
| Core defense | Regenerate ID on login | Prevent leakage (HTTPS, HttpOnly) | Anti-CSRF tokens, SameSite cookies |
CSRF is worth distinguishing here too: a CSRF attack rides along an already-valid session to trigger an unwanted action, while session fixation is about making the session itself belong to the attacker in the first place. They’re solved by different mechanisms and can both be present in the same application independently.
Where this fits in a broader auth strategy
Session fixation is a reminder that session management deserves the same scrutiny as password storage or token signing — it’s easy to treat “the user is logged in” as a solved problem once a framework handles it, but custom session logic is exactly where these bugs creep back in. Systems moving toward passkeys or token-based auth with short-lived JWTs don’t automatically inherit protection either — any code path that accepts an externally supplied identifier and later elevates its privileges on login needs the same regenerate-on-authenticate discipline, regardless of what sits underneath it.
The takeaway
Session fixation works by getting a victim to authenticate under a session ID the attacker already controls, turning a normal login into a login on the attacker’s behalf. The fix is to regenerate the session identifier at the moment of authentication and refuse to trust externally supplied session IDs — a few lines of session-handling logic that most frameworks already get right by default, which is exactly why this bug mostly shows up in code that deviates from those defaults.
Keep reading
Chisato · · 4 min read What Is IDOR? Insecure Direct Object References Explained
IDOR is an access control flaw where an app trusts a user-supplied ID to fetch a record without checking the requester actually owns it.
Chisato · · 4 min read The OAuth PKCE Flow Explained
PKCE hardens the OAuth authorization code flow against interception, and is now recommended for every client type, not just mobile and single-page apps.
Chisato · · 4 min read Cookie Attributes Explained: HttpOnly, Secure, SameSite
HttpOnly, Secure, and SameSite are cookie attributes that block script access, force HTTPS, and limit cross-site sending. Here's what each one actually stops.