How Session Fixation Lets an Attacker Ride a Victim's Login Into Code Execution
🛡️ Security Intermediate 5 min read

How Session Fixation Lets an Attacker Ride a Victim's Login Into Code Execution

An attacker who chooses your session identifier before you log in never needs your password. How session fixation works, why one missing call causes it, and how a hijacked admin session runs code.

Published: October 3, 2026 • Updated: October 3, 2026
session fixationsession hijackingweb application securityauthenticationcwe-384

Session fixationSession Fixation🛡️An attack where the attacker knows or sets a victim's session identifier in advance, then rides that session to gain access once it becomes privileged. It works when a program uses predictable session IDs or fails to regenerate them after login. is one of the oldest web application flaws in the catalogue, and it keeps turning up in modern software because it is a logic error rather than a memory bug. No fuzzer finds it and no compiler flag prevents it. The flaw that opened the door to the DIVD breach in September 2026, CVE-2026-102489 in the Zammad helpdesk, is classified exactly this way: CWE-384, session fixation, leading to session hijackingSession Hijacking🛡️An attack where an adversary takes over a legitimate user session by stealing or predicting session tokens, gaining unauthorized access to systems or data. and then to code execution as the application's service user. The mechanics of that specific bug are still undisclosed. The pattern is not, and understanding it is enough to audit your own applications.

What a session actually is

HTTP has no memory. Every request arrives as a stranger, so a web application hands the browser an identifier after login, usually in a cookie, and from then on treats any request carrying that identifier as the authenticated user. The identifier is the session. Whoever holds it is, as far as the server can tell, the user.

That makes the identifier a bearer credential, and bearer credentials have one rule: the server must be the only party that ever chooses the value, and it must choose a fresh one at every change of privilege. The moment an attacker can influence which identifier a victim ends up using, the attacker no longer needs to steal it. They already know it.

Fixation versus hijacking

Session hijacking is the general term for using someone else's session identifier. The classic routes are stealing it in transit on an unencrypted connection, reading it from a cross-site scripting payload, or finding it in logs and referrer headers. All of those depend on the attacker getting the value after it exists.

Session fixation inverts the order. The attacker obtains a valid identifier first, before anyone has logged in, and then arranges for the victim to authenticate while using it. If the application does not issue a new identifier at login, the attacker's pre-chosen value is now bound to the victim's authenticated account. The attacker never saw the victim's password and never intercepted anything. They simply waited for the victim to upgrade a session they already held.

The delivery mechanisms vary. Older applications accepted session identifiers in URLs, so a link in an email did the job. Applications that accept a client-supplied cookie value and keep using it are vulnerable if the attacker can set a cookie for the domain, which a subdomain, a shared parent domain, or an injection flaw can provide. Some applications expose an endpoint that sets or reflects the session for a legitimate reason, such as a mobile handoff or an embedded widget, and that endpoint becomes the fixation vector. Zammad's own advisory history includes a 2026 fix for a Knowledge Base widget that allowed forced session switching, which shows how such a vector can hide in an unremarkable feature.

Why the fix is one line and still gets missed

The defence is to regenerate the session identifier at every authentication boundary: at login, at logout, at privilege elevation, and when switching users. Most frameworks offer a single call for it. The reason it is missed is that the default behaviour of many session libraries is to preserve the existing session on login so that pre-login state, such as a shopping basket or a return URL, survives. Developers who inherit that default never make a decision about it.

Secondary defences reduce the impact when regeneration is missed. Reject any session identifier the server did not issue. Mark cookies as HttpOnly and Secure so scripts and plaintext connections cannot touch them. Bind the session loosely to the client, for example by invalidating it when the source address or user agent changes abruptly, accepting that this will occasionally log out legitimate users on mobile networks. Keep session lifetimes short for privileged roles and shorter still for administrative consoles.

From a hijacked session to code execution

A stolen session is only as dangerous as the account behind it, which is why the Zammad chain matters. A helpdesk is a privileged application by design. Its administrators configure mail integrations, webhooks, templates, scheduled jobs, and connections to directories and chat platforms. Many of those features exist precisely to make the application do things on the server or reach other systems, so an attacker holding an administrator's session often does not need a second vulnerabilityVulnerability🛡️A weakness in software, hardware, or processes that can be exploited by attackers to gain unauthorized access or cause harm. to run code. They use the features as built.

That is the shape of what DIVD observed: a hijacked session gave code execution as the zammad user, and a separate local flaw, CVE-2026-102490, took that user to root. The second step is where the damage was decided, and it is the step most organisations can harden without waiting for a vendor. The companion guide on how to fence in a web app's service accountService Account🛡️A non-human operating system or application account under which a service runs. Its permissions define the blast radius of any exploit against that service, since attacker code executes with the service account's access to files, secrets, and the network. so a compromise stops short of root walks through that work.

Auditing your own applications

For every web application you run, especially the self-hosted ones a single team owns, answer four questions. Does the session identifier change at login? Log in twice in a browser developer console and compare the cookie values before and after authentication; if they match, you have fixation. Does the application accept an identifier it did not issue? Set an arbitrary value and see whether it is replaced or kept. Can anything set a cookie for the application's domain? Inventory subdomains and shared parents. Finally, what can an administrator session do on the box? If the answer includes running scripts, calling arbitrary URLs, or writing files, treat the session store as a tier-0 secret.

The DIVD intrusion also showed why detection of session misuse has to be behavioural rather than purely signature-based. A fixated session looks like a normal login. The signal was a session suddenly being used from a new source address, followed by behaviour the helpdesk had never shown. The strategic piece on why an autonomous AI attacker collapses your detection window to seconds explains why that signal needs to trigger an automatic response rather than a ticket.