flawopen.com/Vulnerabilities/Session-Fixierung und Cookie-Sicherheit
Session-Fixierung: ID bei Anmeldung erneuern (CWE-384)
Stellen Sie sich vor, ein Reisender wird dazu gebracht, eine Gepäcknummer zu verwenden, die der Angreifer bereits kennt. Behält die Fluggesellschaft diese Nummer nach dem Einchecken bei, könnte der Angreifer den Koffer abholen. Bei einer Session-Fixierung akzeptiert die Anwendung eine Kennung, die der Angreifer dem Opfer vorgeben kann, und macht genau diese Kennung anschließend ohne Erneuerung zur authentifizierten Sitzung. Beide Bedingungen sind nötig; ein Phishing-Link allein fixiert keine Sitzung, sofern die Anwendung diese Kennung nicht akzeptiert oder setzen lässt.
Grundbegriffe und Subsystem-Terminologie
- Session-Fixierung
- Fehler in der Sitzungsverwaltung: Die Anwendung akzeptiert eine dem Angreifer bekannte Kennung und behält sie bei der Anmeldung des Opfers bei.
- Erneuerung der Sitzungs-ID
- Eine neue, nicht vorhersagbare Kennung ausgeben, wenn die Authentifizierung die Sitzungsrechte erhöht. Nur die Sitzungsdaten übernehmen, die erhalten bleiben sollen.
- Cookie-Attribute
Securebeschränkt die Cookie-Übertragung auf HTTPS;HttpOnlyverhindert das Auslesen per JavaScript;SameSitesteuert einen Teil des siteübergreifenden Cookie-Versands. Diese Attribute schützen vor unterschiedlichen Risiken und ersetzen die ID-Erneuerung nicht.- Präfix
__Host- - In unterstützenden Browsern muss ein so benanntes Cookie über HTTPS mit Secure,
Path=/und ohneDomain-Attribut gesetzt werden. Das erschwert es einer benachbarten Subdomain, ein gleichnamiges Cookie für die übergeordnete Domain zu setzen.
Schrittweiser Angriffsablauf
Der Angreifer erhält oder wählt eine Sitzungskennung
Eine separate Schwachstelle oder Funktion ermöglicht es dem Angreifer, eine ID zu erhalten und den Browser des Opfers dazu zu bringen, sie zu senden. Der Weg hängt von der Anwendung ab; ein gewöhnlicher Phishing-Link genügt nicht, wenn Sitzungs-IDs in URLs abgelehnt werden.
Das Opfer verwendet die dem Angreifer bekannte Kennung
Der Browser sendet die ID an die Anwendung, die sie als gültige anonyme Sitzung behandelt. Der Angreifer muss dieselbe Kennung erkennen oder wiederverwenden können.
Die Anmeldung erhöht die Sitzungsrechte
Das Opfer meldet sich an. Verknüpft die Anwendung die authentifizierte Identität mit der vorhandenen ID, statt sie zu erneuern, bezeichnet diese bekannte Kennung nun die authentifizierte Sitzung.
Der Angreifer verwendet die unveränderte Kennung erneut
Kann der Angreifer die ID weiterhin senden und hat der Server sie nicht ungültig gemacht, kann er möglicherweise auf die Sitzung des Opfers zugreifen. Die Erneuerung beim Rechtewechsel unterbricht diese Kette.
Mechanismus und Ursache
Eine Session-Fixierung setzt voraus, dass der Angreifer die vom Opfer verwendete Kennung beeinflusst und die Anwendung sie bei erfolgreicher Anmeldung nicht ersetzt. Cookie-Attribute sind zusätzliche Schutzmaßnahmen, ersetzen aber keine ID-Erneuerung: HttpOnly begrenzt das Auslesen durch Skripte, Secure erzwingt HTTPS, SameSite reduziert bestimmte siteübergreifende Übertragungen und __Host- begrenzt den Cookie-Geltungsbereich in unterstützenden Browsern.
# VULNERABLE: custom session code keeps the pre-authentication ID.
def login_view(request):
user = authenticate(request, request.POST["username"],
request.POST["password"])
if user is not None:
# BUG: privilege changes, but the session ID does not.
request.session["user_id"] = user.pk
request.session["authenticated"] = True
return redirect("/account/")
return redirect("/login/")
# HARDENED: Django login() rotates the session key on authentication.
from django.contrib.auth import authenticate, login
def login_view(request):
user = authenticate(request, request.POST["username"],
request.POST["password"])
if user is not None:
# Uses Django's supported authentication/session integration.
login(request, user)
return redirect("/account/")
return redirect("/login/")
# settings.py: use HTTPS, host-only scope, and a deliberate SameSite policy.
SESSION_COOKIE_NAME = "__Host-sessionid"
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = "Lax"
SESSION_COOKIE_PATH = "/"
SESSION_COOKIE_DOMAIN = None
Angriffssequenz und konzeptionelles Beispiel
- 1Voraussetzung: Eine separate Schwachstelle oder Funktion erlaubt dem Angreifer, die vom Browser des Opfers gesendete ID zu beeinflussen.
- 2Bekannte ID: Der Angreifer kann dieselbe anonyme Sitzungs-ID erkennen oder wiederverwenden.
- 3Authentifizierung: Das Opfer meldet sich an, während der Browser weiterhin die bekannte ID sendet.
- 4Keine Erneuerung: Die Anwendung stuft die bestehende Sitzung hoch, statt ihre Kennung zu ersetzen.
- 5Bedingte Auswirkung: Der Angreifer kann nur zugreifen, solange die bekannte ID gültig und verwendbar bleibt.
Checkliste für technische Abwehrmaßnahmen
- ✓ID bei Rechtewechsel erneuern: Bei Anmeldung und anderen Rechteerhöhungen eine neue, nicht vorhersagbare ID ausgeben; die alte gemäß dokumentiertem Framework-Verhalten ungültig machen.
- ✓Authentifizierungs-APIs des Frameworks verwenden: Die vorgesehene Login- und Sitzungsintegration nutzen (bei Django
django.contrib.auth.login()), statt Identitätsfelder manuell an die Sitzung anzuhängen. - ✓Angreifergesteuerte IDs ablehnen: Keine Sitzungskennungen in URLs akzeptieren. Cookie-Injektion durch benachbarte Subdomains verhindern und eigene Cookie-/Sitzungslogik testen.
- ✓Cookie-Attribute ihrem Zweck entsprechend setzen:
SecureundHttpOnlyverwenden;__Host-mitPath=/und ohneDomainerwägen.SameSite=LaxoderStrictpassend zu legitimen siteübergreifenden Anmeldeflüssen wählen; SameSite ersetzt erforderliche CSRF-Token nicht. - ✓Den Übergang testen: In einem automatisierten Test die anonyme ID erfassen, authentifizieren, den ID-Wechsel prüfen und bestätigen, dass die alte ID keinen Zugriff auf die authentifizierte Sitzung erlaubt.