Session Fixation - Session-Übernahme durch vorgegebene Session-ID
Session Fixation ist ein Angriff bei dem ein Angreifer eine gültige Session-ID an ein Opfer übergibt und wartet bis das Opfer sich mit dieser vorgegebenen Session authentifiziert. Im Gegensatz zu Session-Hijacking (Stehlen einer bestehenden Session) fixiert der Angreifer die Session-ID vor der Anmeldung. Nach der Authentifizierung nutzt der Angreifer die bekannte Session-ID für autorisierten Zugriff. Schutz: neue Session-ID nach Login generieren, SameSite-Cookies, HttpOnly-Flag.
Session Fixation nutzt eine häufige Fehlimplementierung im Session-Management: Die Anwendung generiert eine neue Session-ID nicht nach dem Login, sondern behält die vorhandene bei. Ein Angreifer der die Session-ID vor dem Login kennt (weil er sie selbst gesetzt hat), hat nach der Anmeldung des Opfers vollen Zugriff auf die authentifizierte Session.
Angriffsprinzip
Session Hijacking vs. Session Fixation
Session Hijacking (klassisch):
- Opfer loggt sich ein → neue Session-ID generiert
- Angreifer stiehlt Session-ID (XSS, Netzwerk-Sniffing)
- Angreifer nutzt gestohlene Session
Session Fixation (anders):
- Angreifer kennt eine gültige Session-ID (z.B. von eigener Registrierung)
- Angreifer gibt diese ID an Opfer weiter (URL, Cookie-Manipulation)
- Opfer loggt sich ein → Session-ID bleibt gleich (Fehler!)
- Angreifer hat volle Kontrolle über die authentifizierte Session!
Ablauf Step-by-Step
Schritt 1 - Angreifer erhält gültige Session-ID:
GET https://bank.com/
→ Set-Cookie: SESSIONID=abc123def456 (Server sendet Session für Anon-User)
Schritt 2 - Angreifer gibt Session-ID an Opfer:
- Methode A (URL-Parameter, früher möglich):
https://bank.com/login?SESSIONID=abc123def456→ Opfer klickt Link, Browser übernimmt Session-ID aus URL - Methode B (JavaScript-basiert, heute häufiger): XSS auf einer Sub-Seite von bank.com setzt
document.cookie = "SESSIONID=abc123def456"- setzt Angreifer-Session-ID im Browser des Opfers - Methode C (Response-Header-Injection, seltener): Wenn Angreifer HTTP-Response beeinflussen kann
Schritt 3 - Opfer loggt sich ein:
POST https://bank.com/login
Cookie: SESSIONID=abc123def456
Body: username=alice&password=SECRET
Verwundbare Anwendung:
- Prüft Credentials: korrekt!
- Session-Variablen setzen:
session['user'] = 'alice' - Session-ID nicht erneuern! ← Fehler!
- Antwort:
200 OK, Cookie:SESSIONID=abc123def456
Schritt 4 - Angreifer greift auf Session zu:
GET https://bank.com/account
Cookie: SESSIONID=abc123def456
→ Angreifer hat authentifizierten Zugriff als Alice!
Erkennung im Pentest
Session-Fixation-Test
-
Session-ID vor Login aufzeichnen:
GET https://target.com/→SESSIONID=XYZ(notieren!) -
Login durchführen:
POST https://target.com/loginmitCookie: SESSIONID=XYZund gültigen Credentials -
Session-ID nach Login prüfen: Response-Header:
Set-Cookie: SESSIONID=...?- Sicher: neue Session-ID nach Login (≠ XYZ)
- Unsicher: gleiche Session-ID (= XYZ) → Session Fixation!
-
Burp Suite Test:
- Proxy → HTTP History
- Pre-Login-Request: Session-Cookie notieren
- Post-Login-Request: Cookie vergleichen
- Gleich? → Finding!
Tiefere Prüfung
- Session-ID in URL-Parameter akzeptiert? (z.B.
?PHPSESSID=xyz) - Anderes Session-Cookie nach Logout + Re-Login?
- Session nach Passwortänderung invalidiert?
- Session nach Rechteentzug sofort ungültig?
Verwandte Session-Schwachstellen
- Session nach Logout nicht invalidiert (serverseitig)
- Session-ID zu kurz / vorhersagbar
- Session-ID in URL (Referrer-Leakage, Logs!)
- Session-ID in Browser-Historie (wenn in URL)
- Keine Session-Expiry bei Inaktivität
Schutzmaßnahmen
1. Kritisch: Neue Session-ID nach Authentifizierung
// PHP:
session_regenerate_id(true); // true = altes Session-ID löschen!
// MUSS unmittelbar nach erfolgreicher Authentifizierung aufgerufen werden!
# Python (Flask):
session.clear() # Alte Session löschen
session['user'] = user_id # Neue Session-Daten
// Java (Spring Security):
// Automatisch durch Spring Security!
// SessionManagementConfigurer: session-fixation = change-session-id
// Node.js (express-session):
req.session.regenerate((err) => {
req.session.userId = user.id;
res.redirect('/dashboard');
});
2. Session-ID nur via Cookie (nicht via URL-Parameter)
# PHP ini:
session.use_only_cookies = 1
session.use_trans_sid = 0
session.cookie_httponly = 1
session.cookie_secure = 1
session.cookie_samesite = Strict
3. Cookie-Attribute richtig setzen
Set-Cookie: SESSIONID=...; HttpOnly; Secure; SameSite=Lax; Path=/
- HttpOnly: kein JavaScript-Zugriff (verhindert XSS-basierte Fixation)
- Secure: nur über HTTPS übertragen
- SameSite=Strict: kein Cross-Site-Senden (verhindert CSRF + Fixation via Redirect)
4. Session-Lebensdauer begrenzen
- Absolute Timeout: Session nach 8 Stunden immer invalidieren
- Idle Timeout: Session nach 30 Minuten Inaktivität invalidieren
- Nach Logout: Session serverseitig löschen (nicht nur Cookie!)
5. Nach Logout richtig invalidieren
// Falsch: nur Cookie löschen
setcookie('SESSIONID', '', -1, '/');
// → Server hält Session noch! Angreifer mit alter Cookie kommt noch rein!
// Richtig: Session SERVERSEITIG vernichten:
session_destroy(); // PHP
req.session.destroy(); // Node.js
SecurityContextHolder.clearContext(); // Spring