Security Cipher

Security Resources

⌘K
  1. Home
  2. Security Resources
  3. Vulnerability Explain
  4. Session Fixation

Session Fixation

This Vulnerability Explain post covers Session Fixation, a session management flaw where an attacker gets the victim to use a session identifier the attacker already knows. Once the victim logs in, the attacker rides the same session. Let’s see how it happens and how to stop it.

What is Session Fixation?

Session Fixation occurs when an application accepts a session identifier supplied or influenced by an attacker and does not issue a fresh one when the user authenticates. The attacker knows the session id before login, and after the victim logs in, that id is now authenticated.

Imagine an app that puts the session id in the URL and keeps the same id after login. An attacker sends the victim a link containing a session id the attacker chose. The victim clicks, logs in, and the session – still under that known id – is now valid for the attacker too.

How does Session Fixation work?

Session fixation plays out in a few clear steps:

  • Attacker Obtains a Session Id
    • The attacker gets a valid session id from the app or simply sets one they control.
  • Id Is Planted on the Victim
    • Via a crafted link, cookie, or parameter, the victim’s browser adopts that session id.
  • Victim Authenticates
    • The victim logs in, but the application keeps the same session id instead of regenerating it.
  • Session Is Shared
    • The id the attacker knows is now tied to the victim’s authenticated session.
  • Account Access
    • The attacker uses the known id to act as the victim.

The fix is conceptually simple: the moment a user’s privilege level changes – especially at login – the old session id must be retired and a new one issued.

Session fixation diagram showing an attacker fixing a session id that the victim then authenticates with

How session fixation works: the attacker sets a known session id that the victim logs in with.

Tools and Techniques for Session Fixation Testing

Testing focuses on whether the session id changes at login and whether ids can be set externally.

Manual Testing Methodologies

  • Pre-Login Id Capture – Note the session id before login, authenticate, and check whether it stays the same.
  • External Id Injection – Try setting the session id via URL parameter or cookie and see if the app accepts it.
  • Cookie Attribute Review – Inspect cookie flags (HttpOnly, Secure, SameSite) and scope.
  • Logout Behavior – Confirm the session id is invalidated server side on logout.

Automated Scanning Tools

  • Burp Suite Scanner – Flags session fixation and weak session handling.
  • OWASP ZAP – Detects session management issues.
  • Nuclei – Templates check cookie attributes and session behavior.
  • OWASP WSTG – Provides a thorough manual session testing methodology.

Session Fixation Protection Mechanisms

Best Practices for Secure Coding

  • Regenerate the Session at Login
    • Description: Issue a brand new session id immediately after successful authentication.
    • Benefits: Any pre-login id the attacker knows becomes useless.
    • Implementation Tip: Call the framework’s session regeneration on every privilege change.
  • Never Accept External Session Ids
    • Description: Only accept session ids the server issued, and only via secure cookies.
    • Benefits: Attackers cannot plant a chosen id.
    • Implementation Tip: Do not read session ids from URL parameters.
  • Harden Session Cookies
    • Description: Set HttpOnly, Secure, and SameSite on session cookies.
    • Benefits: Reduces theft and cross-site planting.
    • Implementation Tip: Use short timeouts and invalidate on logout.

Best Practices for Organizations

  • Use Vetted Session Frameworks
    • Rely on a mature session manager rather than custom logic.
    • Keep it patched and correctly configured.
  • Transport Security
    • Enforce HTTPS everywhere so session ids are not exposed.
    • Enable HSTS.
  • Testing
    • Verify session regeneration at login in tests.
    • Audit cookie attributes regularly.

Top Session Fixation payloads used by Security Researchers

As a security researcher, knowing the most common payloads helps you detect and prevent these attacks. Use this knowledge ethically and only on systems you are authorized to test. Some sample payloads are shown below.

// Fixing a session id via URL parameter
https://target.com/login;jsessionid=ATTACKERKNOWN123
https://target.com/?sid=ATTACKERKNOWN123
// Planting a cookie before login (if accepted)
Set-Cookie: SESSIONID=ATTACKERKNOWN123
// Test: id before and after login should differ
// before: SESSIONID=abc123  -> after login should NOT be abc123
// Reuse the known id after the victim logs in
Cookie: SESSIONID=ATTACKERKNOWN123

Real-World Example: Shared Session via a Link

An older app accepted the session id from a URL parameter and did not regenerate it on login.

An attacker sent a victim a link containing a session id the attacker had obtained. The victim clicked, logged in, and the app kept that same id as the authenticated session. The attacker, knowing the id, accessed the victim’s account without ever seeing their password.

The fix stopped reading session ids from URLs and regenerated the session id on every login. Session fixation is defeated by one habit: always issue a fresh session when privileges change.

Vulnerable and secure code of Session Fixation

The following example shows the contrast between vulnerable and secure code for Session Fixation. It helps you see how the flaw creeps into real code and the changes that shut it down.

🥺 Vulnerable Code:

<?php
// Vulnerable: keeps the same session id across login
session_start();   // may adopt an id from the request
if (login($_POST['user'], $_POST['pass'])) {
    // No session_regenerate_id() - the pre-login id stays valid
    $_SESSION['authenticated'] = true;
    $_SESSION['user'] = $_POST['user'];
}
?>
  • The session id is not regenerated after authentication.
  • An id the attacker planted before login becomes an authenticated session.

😎 Secure Code:

<?php
// Secure: regenerate the session id on login
session_start();
if (login($_POST['user'], $_POST['pass'])) {
    session_regenerate_id(true);   // issue a fresh id, delete the old
    $_SESSION['authenticated'] = true;
    $_SESSION['user'] = $_POST['user'];
}
// Cookie hardening (php.ini / runtime):
// session.cookie_httponly=1, session.cookie_secure=1,
// session.cookie_samesite=Lax, session.use_only_cookies=1
?>
  • session_regenerate_id(true) retires any attacker-known id at login.
  • Cookie flags and use_only_cookies prevent planting ids via the URL.

Conclusion

Session Fixation is a subtle but fully preventable flaw. Regenerate the session id immediately after login and any privilege change, never accept session ids from URLs or untrusted sources, and harden session cookies with HttpOnly, Secure, and SameSite. A session should only ever be trusted under an identifier the server minted after the user proved who they are.

How can we help?