flawopen.com/Vulnerabilities/Session Fixation & Cookie Hardening

Session Fixation & Cookie Security Flags

High Severity CWE-384 Cryptography & Auth
ELI5 — The Glued Baggage Claim Ticket

Imagine you walk into an airport and a stranger politely hands you a luggage claim ticket from the dispenser, saying 'I got one for you already!' You thank them, take the ticket, and check your suitcase full of gold into the airplane. Because the stranger wrote down that exact ticket number beforehand, they walk over to the baggage carousel at the destination and claim your gold suitcase before you even arrive. In Session Fixation, an attacker forces a victim to use a known session ID before logging in, stealing their account the second they authenticate.

Target: HTTP session management, authentication cookies
Vector: URL session IDs (?PHPSESSID=xyz), cross-site cookie injection
Impact: Account hijacking without needing user credentials
Remediation: Session token regeneration on login, __Host- cookie prefixes, SameSite=Strict

The Mechanism & Root Cause

When an application does not generate a new session ID upon successful login, the user's authenticated session retains the original session ID issued when they were an anonymous guest. If an attacker pre-allocated or fixed that session ID for the victim (via phishing links or subdomain cookie injection), the attacker's existing browser session becomes immediately authenticated.

login_handler.py (Vulnerable)Vulnerable
# VULNERABLE: Reusing the existing session ID across the authentication boundary
def login_user(request, username, password):
    if authenticate(username, password):
        # BUG: Keeps the existing session ID that was active prior to login!
        request.session['user'] = username
        request.session['authenticated'] = True
        return "Logged in successfully" 
login_handler.py (Hardened)Hardened
# HARDENED: Cycle session ID and issue hardened __Host- cookies
def login_user_safe(request, response, username, password):
    if authenticate(username, password):
        # 1. Destroy old session and generate brand new cryptographic ID
        request.session.cycle_key() 
        request.session['user'] = username
        
        # 2. Issue cookie with modern browser defense flags
        response.set_cookie(
            key="__Host-session_id", # __Host- ensures HTTPS + no subdomains
            value=request.session.session_key,
            httponly=True,           # Disallows JavaScript read access (XSS defense)
            secure=True,             # Transmitted strictly over HTTPS
            samesite="Strict",       # Blocks all cross-site CSRF delivery
            path="/"
        )
        return response

The Attack & Exploit Sequence

Defensive Engineering & Prevention Rules

Explore related security topics and post-mortems: Complete Security Directory →