Skip to content

CWE-384: Session Fixation

Overview

Session Fixation occurs when an application allows an attacker to set or reuse a session identifier for another user, enabling the attacker to hijack the victim's session after authentication.

OWASP Classification

A07:2025 - Authentication Failures

Risk

High: Attackers can impersonate users, access sensitive data, or perform unauthorized actions by controlling session identifiers.

Remediation Steps

Core principle: Never allow a session identifier established prior to authentication to remain valid after authentication; session identifiers must be regenerated whenever a user's authentication or privilege level changes.

Locate the session fixation vulnerability

  • Review the flaw details to identify where session IDs are not regenerated after authentication
  • Check authentication flow: login handlers, OAuth callbacks, SSO integrations
  • Determine if session ID changes after login: compare session ID before and after authentication
  • Identify session ID sources: cookies, URL parameters (dangerous), hidden form fields

Regenerate session IDs after authentication (Primary Defense)

  • Always issue new session ID after successful login: Call session.regenerate(), session_regenerate_id(), or framework equivalent
  • Invalidate old session identifiers: Old session ID must become completely invalid
  • Preserve session data: Copy user data, shopping cart, preferences from old session to new session
  • Regenerate on privilege change: Also regenerate when user role changes (user → admin)
  • Framework methods: Use built-in regeneration (Express: req.session.regenerate(), Django: request.session.cycle_key())

Use secure session management practices

  • Set secure cookie attributes: Secure (HTTPS only), HttpOnly (no JavaScript access), SameSite=Strict (CSRF protection)
  • Limit session lifetime: Short expiry for sensitive operations (15-30 min), absolute timeout (24 hours)
  • Use cryptographically random session IDs: Generate with SecureRandom, os.urandom(), crypto.randomBytes()
  • Sufficient session ID length: Minimum 128 bits (16 bytes) of randomness

Prevent session ID exposure

  • Never accept session IDs from URLs: Don't use GET parameters for session IDs (logged in server logs, browser history)
  • Transmit only in secure cookies: Use HTTP-only cookies, not URL parameters or hidden form fields
  • Reject external session IDs: Don't allow users to specify their own session IDs
  • Use HTTPS only: Ensure all session communication uses HTTPS (Secure flag on cookies)

Monitor and audit session activity

  • Log session creation, regeneration, and termination events
  • Alert on suspicious patterns: duplicate session usage (same session ID from multiple IPs), rapid session creation
  • Track session regeneration after login (verify it's happening)
  • Monitor for session fixation attempts (session ID reuse patterns)
  • Implement session binding: tie session to IP address or user agent (with caution for mobile users)

Test the session fixation fix thoroughly

  • Test session ID changes after login: capture session ID before and after authentication, verify they're different
  • Test old session ID is invalid: attempt to use pre-login session ID after authentication (should be rejected)
  • Verify session data persists: shopping cart, preferences maintained through regeneration
  • Test multiple concurrent logins from different devices
  • Test session attributes: verify Secure, HttpOnly, SameSite flags are set
  • Re-scan with security scanner to confirm the issue is resolved

Dynamic Scan Guidance

For guidance on remediating this CWE when detected by dynamic (DAST) scanners:

Common Vulnerable Patterns

  • Reusing session IDs after authentication
  • Accepting session IDs from GET parameters or external sources

Session ID Not Regenerated After Login (Pseudocode)

# Does not regenerate session ID after login
user = authenticate(username, password)
if user:
    session['user_id'] = user.id  # session_id remains the same!
    # Attacker who set the session ID can now hijack authenticated session

Why this is vulnerable: Failing to regenerate the session ID after authentication allows attackers to perform session fixation attacks by tricking victims into using a pre-set session ID (via URL parameter or cookie injection), then hijacking the authenticated session after the victim logs in with that fixed session identifier.

Secure Patterns

Session Regeneration After Authentication (Pseudocode)

# Regenerate session ID after login
user = authenticate(username, password)
if user:
    session.regenerate_id()  # Create new session ID
    session['user_id'] = user.id
    # Old session ID is now invalid, attacker cannot hijack

Why this works:

  • Generates new session ID after successful authentication, invalidating any pre-set attacker session IDs
  • Prevents session fixation attacks where attacker tricks victim into using a known session ID
  • Blocks attackers from hijacking authenticated sessions by pre-setting the session identifier
  • Ensures attacker-controlled session IDs from URLs or cookies become useless after login
  • Combined with secure session cookie flags (Secure, HttpOnly, SameSite), provides strong session protection

Migration Considerations

IMPORTANT: Implementing session regeneration will log out all currently active users when deployed.

What Breaks

  • All active sessions invalidated: When you deploy session regeneration, existing session IDs become invalid
  • Users logged out: Everyone currently logged in will be forced to re-authenticate
  • Shopping carts cleared: E-commerce sites will lose active cart data if not persisted separately
  • In-progress workflows lost: Multi-step forms or wizards will reset
  • API sessions terminated: If using session-based API authentication

Migration Approach

Option 1: Graceful Session Migration (Recommended)

Migrate sessions gradually without logging everyone out:

  1. Generate new session identifier: Create cryptographically secure random session ID
  2. Copy session data: Migrate all session data from old ID to new ID
  3. Mark old session: Add metadata indicating session was regenerated and where it was regenerated to
  4. Set grace period: Keep old session ID valid for short period (e.g., 60 seconds) to handle in-flight requests
  5. Validate on each request: Check if session was regenerated and redirect to new ID
  6. Trigger regeneration: Regenerate session ID immediately after successful authentication
  7. Preserve user experience: Maintain shopping carts, form data, and other session state through regeneration

Option 2: Big-Bang Session Invalidation (Simple but Disruptive)

Log everyone out at deployment:

  1. Clear all sessions: Remove all session data from session store
  2. Set short expiry: Alternatively, set all existing sessions to expire in 5 minutes
  3. Communicate to users: Send email/notification explaining users need to log in again
  4. Provide context: Explain this is a one-time security enhancement

User Communication Template:

Subject: Security Update - Please Log In Again

We've implemented an important security enhancement that requires all users to log in again. This is a one-time occurrence. Your data is safe. This is a proactive security measure to better protect your account.

Rollback Procedures

If deployment causes issues:

  1. Revert code: Roll back to previous version using version control
  2. Extend session grace period: Increase grace period for old sessions (e.g., from 60 seconds to 1 hour) if users report frequent logouts
  3. Disable regeneration temporarily: Use feature flag to disable session regeneration while investigating issues
  4. Monitor error rates: Check logs for session-related errors since deployment time
  5. Alert on thresholds: Set up alerts if session error rate exceeds normal baseline

Testing Recommendations

Pre-Deployment Testing:

  • Test session regeneration after login
  • Verify old session becomes invalid
  • Test grace period for in-flight requests
  • Verify session data migrates correctly
  • Test concurrent login from multiple devices
  • Verify shopping cart/form data persists
  • Load test: session regeneration performance

Session Regeneration Test Scenarios:

  • Verify new session ID generated after successful authentication
  • Confirm old session ID is rejected after grace period expires
  • Validate session data (cart items, user preferences) persists through regeneration
  • Test multiple concurrent logins from different devices
  • Verify unauthorized access rejected with old session ID
  • Test session validation on each request

Post-Deployment Monitoring:

  • Monitor login/logout rates
  • Track session regeneration events
  • Alert on unusual authentication error rates
  • Monitor support tickets for login issues
  • Track session expiry patterns

Key Metrics to Track:

  • Active session count
  • Session regenerations per hour
  • Failed authentication attempts
  • Sessions in grace period (marked as regenerated)
  • Average session lifetime
  • Session error rate
  • User login/logout frequency

Additional Resources