Documentation

# Session Fixation

Session Fixation Illustration
Session Fixation Illustration

An attack where the attacker sets a victim's session ID to a known value, then waits for the victim to authenticate, allowing the attacker to hijack the authenticated session.

HIGH SEVERITY SESSION HIJACKING AUTHENTICATION


# What is Session Fixation?

In Simple Terms:

Imagine a hotel key card system. Session Fixation is like:

  1. Attacker gets blank key card from hotel
  2. Attacker gives YOU the blank card
  3. You check in using that card - hotel activates it
  4. Attacker uses their copy of the SAME card to access your room!

# How It Works

# Attack Flow

Attacker visits site: https://bank.com
Receives session cookie: SID=abc123
<!-- Phishing email link -->
<a href="https://bank.com/login?SID=abc123">
  Login to your account
</a>

OR via cookie injection:

<script>
document.cookie = "SID=abc123; domain=bank.com";
</script>
Victim clicks link
Logs in with credentials
Session abc123 is now authenticated!
Attacker uses same SID=abc123
Now has access to victim's account!

# Real-World Example

# Banking Platform Attack (2018)

Vulnerability: Session ID accepted from URL parameter

Attack:

1. Attacker sends email: 
   "Verify your account: bank.com/login?sessionid=ATTACKER123"

2. 5000 users click link and login

3. Attacker uses sessionid=ATTACKER123 → Access to all 5000 accounts!

Impact:

  • $8 million stolen
  • 5000 accounts compromised
  • Bank sued for negligence

# Prevention

# 1. Regenerate Session on Login

@app.route('/login', methods=['POST'])
def login():
    username = request.form['username']
    password = request.form['password']
    
    if authenticate(username, password):
        # CRITICAL: Regenerate session ID after login
        session.regenerate()
        
        session['user_id'] = user.id
        session['authenticated'] = True
        return redirect('/dashboard')

# 2. Don't Accept Session ID from URL

# SECURE: Only accept session from cookies
app.config['SESSION_COOKIE_HTTPONLY'] = True
app.config['SESSION_COOKIE_SECURE'] = True
app.config['SESSION_COOKIE_SAMESITE'] = 'Strict'

# Ignore session ID in URL/POST data
@app.before_request
def validate_session_source():
    if 'sessionid' in request.args or 'SID' in request.args:
        return "Invalid request", 400

# 3. Bind Session to User Agent/IP

def create_session(user_id):
    session_id = generate_secure_token()
    
    # Bind to user context
    session_data = {
        'user_id': user_id,
        'user_agent': request.headers.get('User-Agent'),
        'ip_address': request.remote_addr,
        'created_at': time.time()
    }
    
    redis.setex(f'session:{session_id}', 3600, json.dumps(session_data))
    return session_id

def validate_session(session_id):
    data = json.loads(redis.get(f'session:{session_id}'))
    
    # Validate binding
    if data['user_agent'] != request.headers.get('User-Agent'):
        return False
    if data['ip_address'] != request.remote_addr:
        return False
    
    return True

# Security Checklist

  • Regenerate session ID after login
  • Never accept session ID from URL parameters
  • Use HttpOnly, Secure, SameSite cookies
  • Implement session binding (IP, User-Agent)
  • Set session expiration
  • Clear old session on logout
  • Use cryptographically secure session IDs
  • Implement CSRF protection

Last Updated: November 2025