Articles

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.

Chisato Chisato · · 5 min read
A padlock icon over a computer keyboard

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:

  1. 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.
  2. 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.
  3. The victim, unaware anything is wrong, logs in normally through the legitimate site using that session ID.
  4. If the application doesn’t issue a new session ID at login, the session tied to ATTACKERKNOWN123 is 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 HttpOnly so client-side scripts can’t read or set them, and SameSite-restricted so a session ID can’t be planted via a cross-site request. See how cookie attributes like HttpOnly and SameSite work 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 fixationSession hijackingCSRF
Attacker needs to steal a tokenNo — supplies it in advanceYesNo — rides an existing session
Point of compromiseBefore loginAny time after loginDuring an authenticated action
Core defenseRegenerate ID on loginPrevent 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.

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

#Security #Authentication #Web Development
Chisato 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.

#Security #Web Development #Authentication