RC RANDOM CHAOS

Victim types the password, attacker keeps the token

CVE-2023-4714 session fixation (CWE-384) explained: how attackers plant a session ID, bypass MFA, what fires in telemetry, and why rotation alone is not enough.

· 7 min read
Victim types the password, attacker keeps the token

CVE-2023-4714 is a session fixation flaw. Bug class CWE-384. The attacker never sees the password, never runs a cracker, never trips a failed-login counter. The credential that matters is the session identifier, and the application hands the attacker a way to decide what that identifier will be before the victim ever authenticates. CVSS v3 lands in the high range - vector network, attack complexity low, privileges required none, user interaction required. That last metric is the entire exploit. The victim performs the authentication. The attacker supplies the token. The server fuses the two.

This is not memory corruption. No heap spray, no use-after-free, no ROP chain, no sandbox escape. The defect lives in the state machine of the web session - specifically at the privilege boundary between an anonymous session and an authenticated one. A web application issues a session identifier to carry state across stateless HTTP. That identifier is a bearer token. Whoever holds it is the session. Correct behaviour treats the pre-authentication identifier as untrusted and mints a fresh identifier the instant authentication succeeds. The pre-auth token must die at the login boundary. Fixation is what happens when it survives.

The mechanism is narrow and exact. The application accepts a session ID from the client and, on successful login, promotes that same ID to authenticated state instead of regenerating it. The token value is stable across the authentication event. An identifier that was anonymous at 10:00 is the same identifier bound to a logged-in principal at 10:01. If the attacker knew the value at 10:00, the attacker owns the authenticated session at 10:01. The login did not change the secret. It only changed what the secret is allowed to do.

Root cause is trust placement. The server binds identity to a token it did not generate at the moment of trust elevation. The token predates the trust decision. Authentication is supposed to be the point where the system stops trusting attacker-influenceable input and starts trusting a server-minted artifact. Fixation skips that step. The credential flow never re-anchors. CWE-384 is the named weakness; CWE-613, insufficient session expiration, usually rides alongside it, because applications that fail to rotate also tend to fail to expire.

The exploit path is delivery plus patience. The attacker first obtains a valid anonymous session identifier from the target - trivial, since the application issues one to anyone who asks. The attacker then plants that identifier in the victim’s browser. Three vectors dominate. First, query-string propagation: applications that accept the session ID as a URL parameter let the attacker embed a chosen value in a link and deliver it by phishing, MITRE T1566. The victim clicks, lands on the legitimate domain carrying the attacker’s session ID, and logs in. Second, cookie scoping - cookie tossing. A subdomain the attacker controls, or an XSS on any sibling subdomain, writes a cookie scoped to the parent domain. The browser forwards the more permissive cookie and the attacker’s fixed value wins. Third, response header injection: where the application reflects unsanitised input into a Set-Cookie header, the attacker writes the session cookie directly via CRLF. The common denominator across all three - the attacker selects the identifier, the victim authenticates it, the server declines to rotate.

Map to ATT&CK. The planted-token replay is T1550.004, Use Alternate Authentication Material: Web Session Cookie. The session takeover is T1563-class session hijacking. T1539, Steal Web Session Cookie, is the adjacent technique - inverted here, because the attacker plants the cookie rather than lifting it, then collects the authenticated state the victim deposits into it. Delivery is T1566. The detail that matters operationally: this chain walks past MFA. Multi-factor gates the authentication event. The fixed session token is post-authentication material. The victim clears the second factor. The token the attacker already holds inherits the authenticated, MFA-satisfied state. No second factor is requested on replay, because the session is already established. The attacker did not defeat MFA. The attacker stood downstream of it.

Real-world exposure concentrates in federated flows. Session fixation persists in OAuth and SAML handoffs where session state crosses redirects and identity-provider boundaries and where the relying party reuses an identifier minted before the assertion returned. Okta and comparable IdPs issue session tokens that, if the relying party fails to rebind them at the trust boundary, carry the same defect into otherwise modern SSO. Cloudflare and similar edge layers can terminate part of this by enforcing cookie attributes and scoping at the perimeter, but the edge cannot regenerate an identifier the origin refuses to rotate. The control has to live where authentication is decided.

Telemetry is where defenders lose. Session fixation produces almost no host signal. No EDR alert - the attack never lands on an instrumented endpoint. No Sysmon process creation, no Event ID 10 LSASS access, no Event ID 1 anomaly, no malware to fingerprint, no injected thread. The authenticated request the attacker sends is, byte for byte, a valid authenticated request. The host-based detection stack is blind by design, because nothing happens on a host the stack watches. This is a web-tier event, and the web tier is where most SOCs have the least fidelity.

What can fire, if the application is instrumented for it. One: the same session identifier observed from two distinct client fingerprints inside one validity window - different source IP, different ASN, different user-agent, different TLS JA3/JA4. A session token is supposed to live on a single client. Two clients, one token, is the signal. Two: a session identifier present in request logs before the authentication event for that session. The token appears pre-login. In a clean flow the authenticated identifier is born at login; an identifier whose history predates its own login is anomalous on its face. Three: absence of Set-Cookie rotation in the login response. This is inspectable in the application’s own output - the post-auth response should carry a new session cookie. If the login 200 or 302 echoes the inbound session ID, the application is fixation-prone by construction, and that is a detection you can run against your own traffic without an attacker present.

What does not fire is the more important half. No failed-authentication spike - which is exactly what separates this from credential stuffing and password spray. SOC playbooks tuned for authentication anomalies - impossible travel on the login, MFA fatigue prompts, spray velocity, lockout counters - see nothing, because the login itself is legitimate, singular, and successful. The anomaly is on the session token, not the credential. Most SIEM correlation binds alerts to user and credential events. Almost none binds to token-to-fingerprint consistency. That gap is the blind spot, and it is structural, not a tuning problem.

Detection that actually catches this binds every session token to a client fingerprint at issuance and alerts on divergence. Source IP plus user-agent plus JA4, hashed and attached to the session record at login, checked on every subsequent request. Impossible travel applied to the session identifier rather than to the username. A token that authenticated from one ASN and replays from another inside minutes is the event. The correlation rule is cheap. The reason it rarely exists is that the data lives in application logs the SIEM was never fed, not in the authentication logs it was.

The patch boundary is a single piece of logic - regenerate the session identifier on authentication and invalidate the pre-auth token at the same instant. That closes fixation completely. It does not close session theft. Rotation on login does nothing against a token captured after login. An attacker who lifts a post-auth token through an infostealer, an adversary-in-the-middle proxy of the Evilginx class, or an XSS still replays a valid authenticated session, and the rotation that defeats fixation never engages because the token in question was already the rotated one. The patch fixes the bug. It does not fix the category.

The residual exposure is the bearer model itself. As long as the session identifier is a pure bearer credential - valid for anyone who presents it, bound to nothing about the client that earned it - it remains transferable, and a transferable credential is a credential someone will eventually transfer. The durable control is cryptographic binding of the session to the client that authenticated: device-bound session credentials, DPoP, token binding. Bind the token to a key the client holds and a stolen or planted token stops replaying, because possession of the string is no longer possession of the session.

Stealing is a skill because the skill was never breaking the lock. It is being handed the key, and knowing the door was never built to ask who is holding it.

Share

Keep Reading

Stay in the loop

New writing delivered when it's ready. No schedule, no spam.