
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"
}
Danach:
Eine Folgeanfrage mit Sitzung B gab weiterhin authentifizierte Daten von /api/profile zurück.
Das bewies, dass das Problem nicht auf den „Passwort vergessen“/Reset-Pfad beschränkt war.
Es betraf auch normale authentifizierte Passwortänderungen.
Eine Reproduktion hätte bereits ausgereicht, um ein Problem zu zeigen.
Aber die Validierung beider Abläufe war aus zwei Gründen wichtig.
Es zeigte, dass der Fehler nicht auf einen einzelnen Randfall-Wiederherstellungspfad isoliert war.
Dieselbe Sicherheitseigenschaft versagte bei:
Es machte es schwerer, das Problem als versehentliche Geschäftslogik abzutun.
Dies war eindeutig eine breitere Schwäche im Sitzungsmanagement:
Das verlieh dem Problem ein viel stärkeres sicherheitstechnisches Gewicht.
Ich habe den Reset-Ablauf auch mit einem TOTP-aktivierten Konto getestet, weil ich wissen wollte, ob ein Passwort-Reset die 2FA-Erwartungen stillschweigend schwächt oder umgeht.
Was ich bestätigt habe:
Das war eine nützliche Grenzüberprüfung.
Sie grenzte das Problem korrekt ein.
Die Schwachstelle war nicht:
Das eigentliche Problem blieb:
Das ist ein saubererer und besser verteidigbarer Befund.
Dieses Problem wurde angemessen als Hoch eingestuft.
Die Hauptauswirkung hier ist dauerhafter unbefugter Zugriff nach Maßnahmen zur Wiederherstellung der Kontosicherheit.
Die Advisory-Klassifizierung war:
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:NDas ergibt Sinn.
Die Behauptung ist nicht, dass ein Angreifer sich ohne Anmeldedaten von Grund auf anmelden kann. Die Behauptung ist, dass ein Opfer, sobald ein Angreifer eine gültige authentifizierte Sitzung erlangt hat, diesen Zugriff nicht vollständig beenden kann, indem es genau die Sicherheitsmaßnahmen durchführt, die das Konto wiederherstellen sollen, nämlich Passwort-Reset und Passwortänderung.
Das ist eine echte und verteidigbare Schwachstelle im Sitzungsmanagement.
Manche Leute unterschätzen Sitzungspersistenzfehler, weil sie annehmen, dass Sitzungsdiebstahl bereits „Game Over“ ist.
Das ist zu vereinfachend.
Die eigentliche Frage ist, was nach dem Moment passiert, in dem das Opfer merkt, dass etwas nicht stimmt, und handelt.
Wenn:
dann ist die Kontowiederherstellung unvollständig.
Das ist nicht nur unbequemes Verhalten. Das ist ein Sicherheitsfehler im Wiederherstellungsmodell.
Besonders auf einer administrativ ausgerichteten Plattform ist das ein bedeutendes Problem mit starker Vertraulichkeitswirkung.
Der Maintainer hat das Problem in folgendem Commit behoben:
db82035
Die Kernrichtung der Behebung ist genau das, was dieser Fehler brauchte:
Das ist die korrekte Abhilfe, weil sie auf die eigentliche Sicherheitseigenschaft abzielt, die versagt hat:
älteres Vertrauen sollte sterben, wenn sich Anmeldedaten ändern
Eine gute Behebung für diese Fehlerklasse dreht sich nicht um die Änderung der Passwortvalidierung. Es geht darum, zuvor aktiven Sitzungszustand zu widerrufen, der mit dem Konto verbunden ist.
Das ist der Teil, der die tatsächliche Wiederherstellung wiederherstellt.
Dieses Problem wurde privat über den Sicherheitsmeldeablauf von GitHub gemeldet.
Der Maintainer:
CVE-2026-34828
Eine Sache, die während der Bearbeitung des Advisories aufkam, war der Umfang.
Der ursprüngliche Bericht umfasste beides:
GitHub behandelte diese zunächst als unabhängig voneinander behebbare Probleme für die CVE-Zuweisung. Das ist eine nützliche Erinnerung daran, dass der Advisory-Umfang wichtig ist, selbst wenn die zugrunde liegende Schwäche konzeptionell ähnlich ist.
Das Endergebnis war CVE-2026-34828.
Die wichtigste Lektion hier ist einfach:
Das Ändern von Anmeldedaten reicht nicht aus, wenn altes authentifiziertes Vertrauen noch lebendig ist.
Viele Entwickler denken in Begriffen von:
Diese Dinge sind wichtig.
Aber die eigentliche Sicherheitsgrenze ist breiter:
Wenn ein Hochrisiko-Kontoereignis eintritt, welcher zuvor vertraute Zustand muss aufhören, vertrauenswürdig zu sein?
In diesem Fall hätte die Antwort lauten sollen:
Und listmonk tat das nicht.
Das ist die eigentliche Erkenntnis.
Bei dieser Schwachstelle ging es nicht um ausgefallene Payloads oder clevere Parser-Tricks.
Es ging darum, die richtige Vertrauensgrenzen-Frage zu stellen.
In listmonk änderte sich das Passwort.
Die Wiederherstellungsaktion wurde abgeschlossen.
Aber die alte Sitzung des Angreifers lebte weiter.
Deshalb wurde daraus CVE-2026-34828.
