Zum Inhalt springen

Sitzung bleibt nach dem Abmelden gültig

CWE-613OWASP A07:2021Aktualisiert 4. September 20264 Min. Lesezeit

In vielen Anwendungen entfernt die Abmeldeschaltfläche nur das Cookie im Browser, während die Sitzung serverseitig bestehen bleibt. Wer das Token bereits hatte, etwa über einen gemeinsam genutzten Rechner, eine Abhörung oder eine offengelegte Protokollzeile, kann es danach weiter verwenden. Das Abmelden muss die Sitzung auf dem Server vernichten.

Das Abmelden fühlt sich wie ein abgeschlossener Vorgang an: Die Schaltfläche ist gedrückt, die Anmeldemaske erscheint, die Sitzung ist vorbei. Für den Nutzer stimmt dieses Bild. Für den Server gilt es nur, wenn dort auch tatsächlich etwas aufgeräumt wurde. In diesem Artikel lesen Sie, warum dieser Unterschied größer ist, als er wirkt, und wie Sie ihn prüfen.

Was läuft beim Abmelden schief?

Eine Sitzung besteht aus zwei Teilen: einem Wert im Browser des Nutzers und einem zugehörigen Eintrag auf dem Server. Beim Abmelden sollte dieser zweite Teil verschwinden. Bleibt die Sitzung nach dem Abmelden gültig, wurde nur der erste Teil entfernt: Das Cookie ist aus dem Browser gelöscht, der Server akzeptiert den Wert aber weiterhin.

Das ähnelt der Rückgabe eines Zutrittsausweises am Empfang, ohne dass jemand den Ausweis im System deaktiviert. Der Mitarbeiter, der ihn ordnungsgemäß abgibt, bemerkt nichts, denn er kommt ohne ihn nicht mehr hinein. Eine Kopie desselben Ausweises jedoch, irgendwann zuvor angefertigt, öffnet weiterhin sämtliche Türen. Die Rückgabe war eine Geste, keine Maßnahme.

Genau darin liegt der Kern: Das Abmelden ist die einzige Handlung, mit der ein Nutzer seinen eigenen Zugang selbst entziehen kann. Wirkt diese Handlung nur im eigenen Browser, wurde in Wirklichkeit nichts entzogen.

Wie wird eine nach dem Abmelden gültige Sitzung ausgenutzt?

Der Unterschied zwischen einer kosmetischen und einer echten Abmeldefunktion ist im Code gut sichtbar.

Verwundbar:

app.post('/abmelden', (req, res) => {
  res.clearCookie('sid');          // nur der Browser wird aufgeräumt
  res.redirect('/anmelden');
});

Der Nutzer sieht die Anmeldemaske und geht davon aus, dass die Sitzung vorbei ist. Der Sitzungsdatensatz auf dem Server besteht jedoch weiter, mit derselben Kennung und denselben Rechten. Wer diesen Wert zuvor festgehalten hat, kommt damit ohne Weiteres hinein:

GET /konto/daten HTTP/1.1
Host: portal.example
Cookie: sid=8f42c19ade7b3f5c

HTTP/1.1 200 OK

Der Server sieht eine gültige Sitzung und liefert die Daten aus. Dass sich der rechtmäßige Nutzer eine halbe Stunde zuvor abgemeldet hat, ist nirgends festgehalten.

Sicher:

app.post('/abmelden', (req, res) => {
  const sid = req.sessionID;

  req.session.destroy(async (err) => {      // weg aus dem Sitzungsspeicher
    if (err) return res.status(500).send('Abmelden fehlgeschlagen');

    await auditlog.schreibe('abgemeldet', { sid });

    res.clearCookie('sid', {                 // dieselben Attribute wie beim Setzen
      httpOnly: true,
      secure: true,
      sameSite: 'strict',
      path: '/',
    });
    res.set('Cache-Control', 'no-store');
    res.redirect('/anmelden');
  });
});

Der serverseitige Eintrag verschwindet nun zuerst. Das Token verweist danach auf nichts mehr und wird von der Sitzungs-Middleware abgewiesen, gleich wer es mitsendet. Das Aufräumen des Cookies geschieht mit genau denselben Attributen, mit denen es gesetzt wurde; weicht etwa der path ab, bleibt das alte Cookie schlicht im Browser stehen. Cache-Control: no-store verhindert schließlich, dass die vorherige Seite über die Zurück-Schaltfläche wieder aus dem Cache auftaucht.

Widerrufen Sie bei einem Passwortwechsel alle bestehenden Sitzungen, nicht nur die aktuelle. Ein Nutzer, der sein Passwort ändert, weil er Missbrauch vermutet, erwartet damit den Eindringling auszusperren. Bleiben die übrigen Sitzungen gültig, ist diese Erwartung unbegründet und der Angreifer behält seinen Zugang.

Welche Auswirkungen hat eine nach dem Abmelden gültige Sitzung?

Der Schweregrad wird üblicherweise als mittel bewertet, weil eine Bedingung gilt: Der Angreifer muss das Sitzungstoken bereits besitzen. Damit ist dies eine Schwachstelle, die andere Probleme verlängert, statt selbst eines zu eröffnen.

Diese Bedingung schränkt in der Praxis weniger ein, als sie klingt. Sitzungstoken landen an mehr Stellen als erwartet: im Browserverlauf eines gemeinsam genutzten Rechners, in Proxy- und Serverprotokollen, in Fehlerberichten, über eine Abhörung in einem öffentlichen Netz oder über Cross-Site Scripting. In all diesen Fällen ist das Abmelden die Handlung, mit der das Opfer den Schaden begrenzen können sollte, und genau diese Handlung wirkt dann nicht.

Das Szenario, in dem es am häufigsten schiefgeht, ist ganz alltäglich: Jemand meldet sich an einem fremden Rechner an, nutzt ordnungsgemäß die Abmeldeschaltfläche und geht. Der nächste Nutzer braucht nur die Zurück-Schaltfläche oder ein aus dem Verlauf wiederhergestelltes Cookie, um im Konto zu landen. Was der Nutzer als Abschluss betrachtete, erweist sich als offene Tür.

Wie spürt man eine nach dem Abmelden gültige Sitzung auf?

Der Test ist unmittelbar und verlangt wenig Werkzeug. Ein Tester meldet sich an, hält den Wert des Sitzungscookies fest, betätigt die Abmeldung und sendet danach eine Anfrage an eine geschützte Route mit dem alten Token. Folgt ein 200 mit Inhalt statt einer Abweisung, ist der Befund nachgewiesen.

Danach folgen die Varianten, die häufig sehr wohl scheitern. Wird die Sitzung auch bei einem Passwortwechsel vernichtet? Bleiben andere Sitzungen desselben Nutzers gültig, und ist das eine bewusste Entscheidung? Bei Anwendungen mit JSON Web Token wird geprüft, ob überhaupt ein Widerrufsmechanismus besteht, denn ohne serverseitigen Speicher bleibt das Token bis zum Ablauf gültig. Ebenso wird geprüft, ob die Abmelderoute selbst gegen Missbrauch geschützt ist und ob das Cookie mit den richtigen Attributen entfernt wird. AssistSec bezieht zusätzlich die Zurück-Schaltfläche und den Browser-Cache in den Test ein, denn eine korrekt vernichtete Sitzung kann dennoch sensible Seiten preisgeben, wenn diese aus dem Cache neu aufgebaut werden.

Wie verhindert man eine nach dem Abmelden gültige Sitzung?

  • Vernichten Sie beim Abmelden die Sitzung im serverseitigen Speicher und verlassen Sie sich nicht auf das Entfernen des Cookies.
  • Entfernen Sie das Cookie mit exakt denselben Attributen (path, domain, secure, sameSite), mit denen es gesetzt wurde.
  • Widerrufen Sie alle aktiven Sitzungen bei einem Passwortwechsel, einer Rechteänderung oder dem Sperren eines Kontos.
  • Verwenden Sie zum Abmelden eine POST-Anfrage mit CSRF-Schutz, damit niemand einen anderen ungefragt abmelden kann.
  • Senden Sie Cache-Control: no-store auf Seiten mit sensiblem Inhalt, damit die Zurück-Schaltfläche sie nicht wiederherstellt.
  • Arbeiten Sie bei JSON Web Token mit kurzen Gültigkeitsdauern und einer Widerrufsliste oder führen Sie einen Sitzungsstatus auf dem Server.
  • Bieten Sie Nutzern eine Übersicht aktiver Sitzungen und Geräte mit der Möglichkeit, diese einzeln zu beenden.
  • Halten Sie Abmeldezeitpunkte in einem Auditprotokoll fest, damit die Nutzung eines Tokens nach dem Abmelden nachträglich erkennbar ist.

Quellen

Häufige Fragen

Genügt das Entfernen des Cookies nicht?

Nein, denn das ist eine Anweisung an einen einzigen Browser. Das Token selbst bleibt gültig, und jeder, der den Wert bereits kennt, kann ihn weiter mitsenden. Das Abmelden muss die Sitzung im serverseitigen Speicher löschen, damit der Wert nirgends mehr etwas bedeutet.

Warum ist das bei JWT schwieriger?

Ein JWT wird anhand seiner Signatur geprüft und nicht in einer Datenbank nachgeschlagen, der Server hat also keine Stelle, an der er es ungültig machen könnte. Sie benötigen dann eine Widerrufsliste oder eine kurze Gültigkeitsdauer mit Refresh-Token; andernfalls bleibt das Token bis zum Ablauf gültig, wie oft sich der Nutzer auch abmeldet.

Sollte das Abmelden alle Sitzungen beenden?

Nicht zwingend. Nutzer arbeiten häufig auf mehreren Geräten und erwarten, dass das Abmelden am Laptop ihr Telefon nicht schließt. Bei einem Passwortwechsel oder dem Verdacht auf Missbrauch sollten dagegen sehr wohl alle Sitzungen fallen. Bieten Sie zusätzlich eine Übersicht an, in der Nutzer Sitzungen einzeln beenden können.

Was genau sollte das Abmelden tun?

Die Sitzung serverseitig vernichten, das Cookie mit abgelaufenem Datum und denselben Attributen wie beim Setzen entfernen und den Nutzer auf eine Seite führen, die nicht aus dem Cache stammt. Tun Sie das über eine POST-Anfrage mit CSRF-Schutz, damit niemand einen anderen ungefragt abmelden kann.

Verwandte Artikel

Zum Suchen / drücken · Esc