#
Session Fixation
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?
Session Hijacking
Session Fixation allows attackers to hijack authenticated sessions by forcing victims to use attacker-controlled session IDs. Unlike session theft, the attacker sets the session ID BEFORE the victim logs in.
In Simple Terms:
Imagine a hotel key card system. Session Fixation is like:
- Attacker gets blank key card from hotel
- Attacker gives YOU the blank card
- You check in using that card - hotel activates it
- 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