Zum Inhalt springen

Authentifizierungscookie mit zu langer Gültigkeit

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

Ein Authentifizierungscookie mit einem Verfallsdatum von Monaten hält den Nutzer angemeldet, gibt einem Angreifer, der das Token erlangt, jedoch ebenso viel Zeit. Komfort und Risiko laufen hier unmittelbar gegeneinander. Die Lösung besteht nicht darin, eine kurze Sitzung zu erzwingen, sondern die lange Gültigkeit in ein eigenes, widerrufbares und an ein Gerät gebundenes Token zu verlagern.

“Angemeldet bleiben” ist eine der am meisten geschätzten Funktionen jeder Anwendung und zugleich eine der Stellen, an denen Sicherheit am leisesten preisgegeben wird. Ein Häkchen, das den Nutzer monatelang angemeldet hält, hält auch einen Angreifer monatelang angemeldet. In diesem Artikel lesen Sie, wie Sie den Komfort behalten, ohne diesen Preis zu zahlen.

Wie lange darf ein Authentifizierungscookie gelten?

Ein Authentifizierungscookie trägt den Nachweis, dass jemand angemeldet ist. Das Verfallsdatum bestimmt, wie lange dieser Nachweis gilt. Eine zu lange Gültigkeit bedeutet, dass das Token noch Zugang gewährt, lange nachdem der ursprüngliche Anmeldevorgang vergessen ist, mitunter monatelang, mitunter ohne jede Obergrenze.

Die Abwägung ist tatsächlich schwierig, denn beide Seiten sind real. Eine kurze Gültigkeit zwingt Nutzer zu ständigem erneutem Anmelden, was zu schwächeren Passwörtern, gespeicherten Zugangsdaten und Verdruss führt. Eine lange Gültigkeit ist bequem, verlängert aber genau den Zeitraum, in dem ein gestohlenes Token nutzbar bleibt.

Es ist der Unterschied zwischen einer Tageskarte und einem Schlüssel, den Sie jemandem auf unbestimmte Zeit mitgeben. Beides gewährt Zutritt; nur beim zweiten bleibt das so, auch nachdem Sie vergessen haben, dass Sie ihn ausgegeben haben.

Wie wird ein zu lange gültiges Authentifizierungscookie ausgenutzt?

Verwundbar:

app.post('/anmelden', async (req, res) => {
  const nutzer = await pruefeZugangsdaten(req.body);
  if (!nutzer) return res.status(401).send('Ungültige Daten');

  req.session.userId = nutzer.id;

  res.cookie('sid', req.sessionID, {
    httpOnly: true,
    secure: true,
    maxAge: 365 * 24 * 60 * 60 * 1000,   // ein Jahr
  });
  res.send('Willkommen');
});

Die Sitzung selbst gilt ein Jahr. Wer das Token in die Hände bekommt, hat damit ein Jahr Zugang. Dieses Token landet unterdessen an mehr Stellen als im Browser des Nutzers: in Sicherungen des Profils, auf einem gemeinsam genutzten Rechner, an den niemand mehr denkt, in einem Abgleichdienst zwischen Geräten oder bei jemandem, der den Laptop später übernimmt. Es gibt keinen zweiten Kontrollpunkt, an dem sich die Anwendung fragt, ob dieser Nutzer noch dazugehört.

Sicher:

const SITZUNG_MAX = 8 * 60 * 60 * 1000;             // 8 Stunden
const MERKEN_MAX = 30 * 24 * 60 * 60 * 1000;        // 30 Tage

app.post('/anmelden', async (req, res) => {
  const nutzer = await pruefeZugangsdaten(req.body);
  if (!nutzer) return res.status(401).send('Ungültige Daten');

  req.session.regenerate(async () => {
    req.session.userId = nutzer.id;
    req.session.gestartetAm = Date.now();

    res.cookie('__Host-sid', req.sessionID, {
      httpOnly: true, secure: true, sameSite: 'strict',
      path: '/', maxAge: SITZUNG_MAX,
    });

    if (req.body.angemeldetBleiben) {
      // Eigenes Token: nur zum Starten einer neuen Sitzung geeignet
      const roh = randomBytes(32).toString('base64url');
      await merkenTokens.speichere({
        nutzerId: nutzer.id,
        hash: sha256(roh),                       // nie das Token selbst speichern
        laeuftAbAm: Date.now() + MERKEN_MAX,
        geraet: req.get('user-agent'),
      });
      res.cookie('__Host-merken', roh, {
        httpOnly: true, secure: true, sameSite: 'strict',
        path: '/', maxAge: MERKEN_MAX,
      });
    }
    res.send('Willkommen');
  });
});

Die Sitzung ist nun kurz, und die lange Gültigkeit steckt in einem eigenen Token mit eigener Aufgabe. Dieses Token gewährt keinen unmittelbaren Zugang: Es liefert allenfalls eine neue Sitzung. Es ist als Hashwert gespeichert, sodass ein Datenbankleck die Token nicht preisgibt, es ist an ein Gerät gebunden, und es ist widerrufbar. Wird es genutzt, gibt der Server ein neues Token aus, und das alte verfällt; legt jemand danach dennoch das alte Token vor, ist das ein deutliches Signal, dass eine Kopie im Umlauf ist.

Fragen Sie bei sensiblen Vorgängen stets erneut nach dem Passwort, wenn die Sitzung aus einem Angemeldet-bleiben-Token wiederhergestellt wurde. Der Nutzer hat nämlich nicht nachgewiesen, dass er das Passwort kennt; er hat nur nachgewiesen, dass er ein Token besitzt. Für das Ändern eines Passworts, einer E-Mail-Adresse oder von Zahlungsdaten ist das zu wenig.

Welche Auswirkungen hat ein zu lange gültiges Authentifizierungscookie?

Der Schweregrad wird üblicherweise als niedrig bis mittel bewertet, denn ein unmittelbarer Angriff ist nicht möglich: Der Angreifer benötigt das Token. Was dieser Befund bewirkt, ist eine Vergrößerung des Werts jedes anderen Lecks.

Ein Sitzungstoken kann auf viele Weisen nach außen gelangen, über Cross-Site Scripting, eine unverschlüsselte Anfrage, eine Protokolldatei, ein Bildschirmfoto oder schlicht einen Rechner, der den Besitzer wechselt. Bei einer Sitzung von acht Stunden ist der Schaden daraus begrenzt. Bei einer Sitzung von einem Jahr hat der Angreifer alle Zeit: Er kann bis außerhalb der Bürozeiten warten, in Ruhe erkunden und zu einem selbst gewählten Zeitpunkt zuschlagen, ohne dass ein zweiter Anmeldeversuch Alarm auslösen könnte.

Es gibt auch eine organisatorische Seite. Bei langer Gültigkeit verlieren Sie den Überblick darüber, wer noch Zugang hat. Ausgeschiedene Mitarbeiter, ausgemusterte Geräte und Konten, deren Rechte entzogen wurden, behalten sämtlich ein gültiges Token, sofern Sie das nicht aktiv erzwingen.

Wie spürt man ein zu lange gültiges Authentifizierungscookie auf?

Das Verfallsdatum des Cookies lässt sich unmittelbar aus dem Set-Cookie-Header ablesen, und das ist der Ausgangspunkt. Wichtiger ist die Frage, ob dieses Datum überhaupt etwas bedeutet: Ein Tester entfernt das Verfallsdatum aus dem Cookie und prüft, ob das Token dennoch akzeptiert wird. Geschieht das, wird die Gültigkeit nur vom Browser überwacht und serverseitig gar nicht.

Ebenso wird betrachtet, wie die Angemeldet-bleiben-Funktion aufgebaut ist. Handelt es sich um dasselbe Session-Cookie mit längerer Laufzeit oder um ein eigenes Token? Wird dieses Token als Hashwert gespeichert? Rotiert es bei Nutzung? Bleibt es nach einem Passwortwechsel gültig? Und wird bei sensiblen Vorgängen erneut authentifiziert, wenn die Sitzung aus einem solchen Token wiederhergestellt wurde? AssistSec beurteilt diese Fragen als Ganzes, denn eine lange Gültigkeit mit einem gut aufgebauten, widerrufbaren und rotierenden Token ist vertretbar, während dieselbe Laufzeit am Session-Cookie selbst es nicht ist.

Wie verhindert man ein zu lange gültiges Authentifizierungscookie?

  • Halten Sie das Session-Cookie kurz und verlagern Sie eine längere Gültigkeit in ein eigenes Angemeldet-bleiben-Token.
  • Überwachen Sie die Gültigkeit serverseitig; verlassen Sie sich nie allein auf das Verfallsdatum im Cookie.
  • Speichern Sie Angemeldet-bleiben-Token als Hashwert, damit ein Datenbankleck keine nutzbaren Token liefert.
  • Rotieren Sie das Token bei jeder Nutzung und widerrufen Sie alles, sobald ein abgelaufenes oder wiederverwendetes Token vorgelegt wird.
  • Binden Sie das Token an ein Gerät und zeigen Sie dem Nutzer eine Übersicht aktiver Geräte.
  • Widerrufen Sie alle Token bei einem Passwortwechsel, einer Rechteänderung oder dem Sperren eines Kontos.
  • Verlangen Sie bei sensiblen Vorgängen innerhalb einer wiederhergestellten Sitzung eine erneute Authentifizierung.
  • Stimmen Sie die Höchstlaufzeit auf die Sensibilität der Anwendung ab und halten Sie diese Entscheidung in Ihrer Richtlinie fest.

Quellen

Häufige Fragen

Darf ich Nutzer gar nicht lange angemeldet lassen?

Doch, aber nicht mit dem Session-Cookie selbst. Verwenden Sie dafür ein eigenes Angemeldet-bleiben-Token, das nur zum Anlegen einer neuen Sitzung berechtigt. Dieses Token können Sie widerrufen, an ein Gerät binden und bei Nutzung rotieren, während die eigentliche Sitzung kurz bleibt.

Was ist ein Session-Cookie ohne Verfallsdatum?

Ein Cookie ohne Expires oder Max-Age wird vom Browser entfernt, sobald dieser geschlossen wird. Für die Authentifizierung ist das meist die sicherste Wahl. Beachten Sie aber: Viele Browser stellen beim Start die vorherige Sitzung samt Cookies wieder her, verlassen Sie sich also nicht blind darauf.

Warum muss ein Angemeldet-bleiben-Token rotieren?

Damit eine Wiederverwendung sichtbar wird. Geben Sie bei jeder automatischen Wiedererkennung ein neues Token aus und wird später dennoch ein altes Token vorgelegt, existiert offenbar eine Kopie. Das ist der Moment, alle Token dieses Nutzers zu widerrufen und ihn zu warnen.

Genügt es, das Verfallsdatum zu verkürzen?

Nur wenn der Server diese Grenze auch selbst überwacht. Das Verfallsdatum eines Cookies ist eine Anweisung an den Browser und sagt nichts über die Gültigkeit des Tokens aus. Ein Angreifer sendet den Wert einfach nach diesem Datum; wird das serverseitig nicht geprüft, ändert sich nichts.

Verwandte Artikel

Zum Suchen / drücken · Esc