FlawOpen

flawopen.com/Vulnerabilities/Session-Fixierung und Cookie-Sicherheit

Session-Fixierung: ID bei Anmeldung erneuern (CWE-384)

High Severity CWE-384 Cryptography & Auth
💡 Einfach erklärt — der festgeklebte Gepäckschein

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.

Ziel: serverseitige Sitzungsverwaltung und die Kennung des authentifizierten Browsers.
Voraussetzung: Der Angreifer kann das Opfer dazu bringen, eine bekannte Sitzungs-ID zu verwenden, etwa über akzeptierte IDs in URLs oder Cookie-Injektion.
Fehler: Die Anwendung behält die dem Angreifer bekannte ID beim Wechsel von der anonymen zur authentifizierten Sitzung bei.
Abhilfe: Bei der Authentifizierung eine neue, nicht vorhersagbare ID ausgeben; Cookie-Attribute getrennt nach Bedrohung konfigurieren.

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
Secure beschränkt die Cookie-Übertragung auf HTTPS; HttpOnly verhindert das Auslesen per JavaScript; SameSite steuert 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 ohne Domain-Attribut gesetzt werden. Das erschwert es einer benachbarten Subdomain, ein gleichnamiges Cookie für die übergeordnete Domain zu setzen.

Schrittweiser Angriffsablauf

Step 1

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.

Step 2

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.

Step 3

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.

Step 4

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.

login_view.py (Unsicheres Muster)Unsicher
# 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/")
login_view.py (Sicheres Django-Beispiel)Abgesichert
# 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

Checkliste für technische Abwehrmaßnahmen

Quellen und verwandte Sicherheitsthemen:Vollständiges Sicherheitsverzeichnis →
CWE-384: Session-Fixierung → OWASP: Leitfaden zur Sitzungsverwaltung → OWASP WSTG: Session-Fixierung testen → Django: Sitzungen und cycle_key() → MDN: HTTP-Cookies und Präfixe →