Bulwark Webmail: Fremde Seite schreibt das Sitzungscookie des Opfers um
POST /api/auth/session schreibt das Sitzungscookie aus einem unangemeldeten Anfragerumpf und traegt keine CSRF-Pruefung
Advisory-ID: TP-2026-104
Produkt: Bulwark Webmail (Weboberflaeche fuer den Mailserver Stalwart, Next.js)
Schwachstellentyp: Cross-Site Request Forgery (CWE-352)
CVE: beantragt am 19. September 2026 (GitHub CNA), Vergabe ausstehend
CVSS 3.1: 6.3 (Mittel) · CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:L
Betroffene Versionen: 1.3.0 bis 1.9.2
Hersteller-Advisory: GHSA-qvr9-m8cq-7wvg
Behoben in: 1.10.0
Gemeldet: 16. September 2026
Zusammenfassung
Der Endpunkt, der das Sitzungscookie der Webmail setzt, nimmt seinen Inhalt aus dem Rumpf einer unangemeldeten Anfrage entgegen und prueft nicht, ob die Anfrage von der eigenen Seite stammt. Ein Formular auf einer fremden Seite erzeugt mit dem passenden Kodierungstyp einen Rumpf, den der Server als JSON einliest. Eine beliebige Seite ueberschreibt damit das Cookie eines angemeldeten Opfers mit Zugangsdaten, die der Angreifer waehlt. Da der Handler bei einer von der Administration eingerichteten Serveradresse auf die Rueckfrage beim Mailserver verzichtet, muessen diese Zugangsdaten nicht einmal gueltig sein. Die Anzeige in der Seitenleiste bleibt unveraendert, weil die Identitaet im Browserspeicher unberuehrt bleibt.
Ursache
POST /api/auth/session schreibt das Sitzungscookie aus dem Anfragerumpf und traegt keinerlei Pruefung auf die Herkunft der Anfrage. Die Methode PUT in derselben Datei ist durch eine dreifache Abfrage der Sec-Fetch-Kopfzeilen abgesichert, und die Oberflaeche der Administration bringt eine eigene Hilfsfunktion fuer die Pruefung gleicher Herkunft mit; keines von beidem erreicht auch nur einen der neun POST-Handler unterhalb von /api/auth/. Ein Formular mit dem Kodierungstyp text/plain erzeugt einen Rumpf, den request.json() einliest, weshalb die Anfrage ohne Vorabanfrage durchgeht. Die Voreinstellung cookieSameSite: 'lax' (lib/oauth/cookie-config.ts:6) haelt das nicht auf, denn das Cookie wird bei einer Navigation der obersten Ebene ueber Set-Cookie geschrieben und nicht aus einer solchen gelesen. Drei der ungeschuetzten Routen schreiben Identitaetscookies, naemlich /api/auth/session, /api/auth/stalwart-context und /api/auth/totp-token-exchange.
Proof of Concept
<!-- Fremde Seite, vom angemeldeten Opfer besucht -->
<form action="https://webmail.example/api/auth/session"
method="POST" enctype="text/plain">
<input name='{"username":"[email protected]","serverUrl":"'
value='<eingerichteter server>","x":"}'>
</form>
<script>document.forms[0].submit()</script>
<!-- Der Rumpf wird als JSON eingelesen, der Server setzt das
Sitzungscookie auf das Postfach des Angreifers. -->
Fuer die Variante mit untergeschobener Sitzung muss das Opfer angemeldet sein; fuer die blosse Verweigerung des Dienstes genuegt ein geoeffneter Browser. Die Option, angemeldet zu bleiben, wird nicht gebraucht: die normale Anmeldung schreibt dieses Cookie nur, wenn sie gesetzt ist, der Angriff schreibt es ohne Bedingung.
Auswirkung
- Eine beliebige Seite laesst den Browser des angemeldeten Opfers eine dreissig Tage gueltige Sitzung fuer das Postfach des Angreifers halten.
- Alles, was das Opfer danach schreibt oder ablegt, landet im Postfach des Angreifers, waehrend die Seitenleiste weiter die eigene Adresse zeigt.
- Verweigerung des Dienstes durch ein Cookie ohne gueltiges Postfach, wofuer ein geoeffneter Browser genuegt.
- Zwei weitere ungeschuetzte Routen schreiben ebenfalls Identitaetscookies.
Referenzen
Steckt so etwas in Ihrer Software?
Diese Schwachstelle hat unser Team im Rahmen seiner Arbeit gefunden. Lassen Sie Ihre Anwendungen von denselben Spezialisten prüfen, mit einem Penetrationstest von turingpoint.
