
listmonks Sitzungspersistenz nach Passwort-Reset und Passwortänderung
listmonks Sitzungspersistenz nach Passwort-Reset und Passwortänderung
Ich habe dieses Problem bei der Überprüfung von listmonk, einem quelloffenen Newsletter- und Mailinglisten-Manager, mit einer einfachen Sicherheitsfrage im Hinterkopf gefunden:
Wenn ein Benutzer ein Passwort ändert oder zurücksetzt, beendet die Anwendung tatsächlich bereits ausgestellte Sitzungen?
In diesem Fall lautete die Antwort nein.
Zuvor ausgestellte authentifizierte Sitzungen blieben sowohl nach:
gültig.
Das bedeutete, dass ein gestohlenes Sitzungscookie genau die Sicherheitsereignisse überleben konnte, auf die sich Benutzer verlassen, um ihr Konto wiederherzustellen.
Das Problem wurde akzeptiert und als CVE-2026-34828 zugewiesen.
Projekt: listmonk auf GitHub
CVE: CVE-2026-34828
Dies betraf listmonk, ein weit verbreitetes Projekt mit 5M+ Docker-Pulls.
gestohlene authentifizierte Sitzung → Opfer setzt Passwort zurück oder ändert es → alte Sitzung bleibt gültig → Angreifer behält Kontozugriff nach der Wiederherstellung der Anmeldedaten
listmonk ist ein selbst gehosteter Mailinglisten- und Newsletter-Manager.
Es bietet:
Das bedeutet, dass sein Sitzungsmodell eine echte Sicherheitsgrenze darstellt.
Die wichtige Frage hier war nicht, ob listmonk das Zurücksetzen von Passwörtern unterstützt.
Die eigentliche Frage war:
Setzt ein Passwort-Reset oder eine Passwortänderung tatsächlich die Persistenz des Angreifers außer Kraft, wenn eine Sitzung bereits gestohlen wurde?
In diesem Fall tat es das nicht.
Viele Sicherheitsüberprüfungen konzentrieren sich zu eng auf Login-Bypasses und offensichtliche Privilegieneskalation.
Dadurch wird eine wichtige Klasse von Schwachstellen übersehen:
Fehler bei der Wiederherstellung
Wenn ein Benutzer ein Passwort ändert oder zurücksetzt, soll diese Aktion eine Bedeutung haben.
Sie soll das Vertrauen in ältere Anmeldedaten und alten Authentifizierungsstatus verringern.
Wenn ein Angreifer bereits eine gültige Sitzung hat und diese Sitzung das Wiederherstellungsereignis überlebt, dann hat das Opfer das Konto nicht wirklich vollständig wiederhergestellt.
Genau das war hier das Problem.
Dies war kein Login-Validierungsfehler. Es war kein Krypto-Problem. Es war kein Fehler beim Passwort-Hashing.
Es war ein Fehler im Sitzungslebenszyklus:
Das reicht aus, um eine echte Schwachstelle zu erzeugen.
Ich bin nicht an listmonk herangegangen, indem ich zufällig Endpunkte angegriffen habe und hoffte, dass einer umkippt.
Der stärkere Weg bestand darin, zuerst die Vertrauensgrenze mit dem höchsten Wert zu identifizieren.
Bei stark authentifizierungsintensiver Software ist eine der besten Grenzen, die man testen kann, diese:
Widerrufen sicherheitsrelevante Kontenänderungen zuvor vertraute Sitzungen?
Diese Frage wird normalerweise interessant bei:
Bei listmonk kam das stärkste Signal von den ersten beiden.
Dort wurde das Problem deutlich.
Der Fehler bestand nicht darin, dass Passwortänderungen fehlschlugen.
Der Fehler bestand darin, dass Sitzungen sie überlebten.
Aus der Quellcode-Überprüfung ergab sich folgender Ablauf für den Passwort-Reset:
aber es gab keine sichtbare Sperrung älterer Sitzungen.
Dasselbe Muster trat beim authentifizierten Passwortänderungsablauf auf:
Dieses Verhalten stimmte genau mit den Live-Ergebnissen überein.
Relevante Codebereiche, die ich überprüft habe, waren:
cmd/auth.go für das Verhalten bei „Passwort vergessen“/Resetcmd/users.go für authentifizierte Profilaktualisierungeninternal/core/users.go für die Verarbeitung von PasswortaktualisierungenWeil Sitzungsdiebstahl eine reale Angriffsbedingung ist.
Sobald ein Angreifer auf irgendeine Weise ein gültiges authentifiziertes Sitzungscookie erlangt, etwa durch:
sollte das Opfer in der Lage sein, diese Persistenz des Angreifers durch Ändern oder Zurücksetzen des Passworts zu beenden.
Hier konnten sie es nicht.
Die Angriffskette war unkompliziert:
Das ist die gesamte Schwachstelle.
Der wichtige Unterschied ist die Persistenz nach der Wiederherstellung.
Viele Anwendungen behandeln die Passwortänderung als reines Ereignis auf Anmeldedatenebene. Das ist nicht genug.
Die eigentliche Frage ist nicht:
„Hat sich der Passwortwert im Speicher geändert?“
Die eigentliche Frage ist:
„Wurde die Vertrauensbeziehung, die an ältere Sitzungen gebunden ist, widerrufen?“
In listmonk wurde sie nicht widerrufen.
Das verwandelt das, was eine gewöhnliche Kontowartung hätte sein können, in eine unvollständige Sicherheitswiederherstellung.
Das ist der Unterschied zwischen:
Ich habe das Problem in zwei separaten Abläufen validiert.
Zuerst erstellte ich einen normalen Testbenutzer und meldete mich an, wobei ich das authentifizierte Sitzungscookie speicherte.
Dann löste ich den „Passwort vergessen“-Ablauf aus, erfasste den Reset-Link und setzte das Passwort zurück.
Nach dem Reset:
Eine repräsentative Validierungsanfrage sah so aus:
GET /api/profile HTTP/1.1
Host: 127.0.0.1:9000
Cookie: session=<old_pre_reset_session>
Und der Server gab weiterhin zurück:
HTTP/1.1 200 OK
Content-Type: application/json
mit dem authentifizierten Profil.
Das untermauerte die Kernaussage:
Anschließend validierte ich dieselbe Fehlerklasse im authentifizierten Passwortänderungsablauf.
Ich meldete mich zweimal als derselbe Benutzer an und speicherte zwei gültige authentifizierte Sitzungen:
Mit Sitzung A änderte ich das Passwort über den Profilaktualisierungs-Endpunkt.
Beispielanfrage:
PUT /api/profile HTTP/1.1
Host: 127.0.0.1:9000
Cookie: session=<session_A>
Content-Type: application/json
{
"name":"victim1",
"email":"[email protected]",
"password":"VictimChanged123"
}