VoidAuth: Der zweite Faktor laesst sich unbegrenzt durchprobieren
Die TOTP-Pruefung kennt keinen Zaehler je Konto, und die einzige Bremse haengt an einer Adresse, die der Aufrufer selbst setzt.
Advisory-ID: TP-2026-096
Produkt: VoidAuth (Anmeldedienst und Identitaetsanbieter zur Selbstverwaltung, TypeScript)
Schwachstellentyp: Unzureichende Begrenzung von Anmeldeversuchen (CWE-307)
CVE: beantragt (GitHub CNA), Vergabe ausstehend
CVSS 3.1: 6.8 (Mittel) · CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:N
Betroffene Versionen: <= 1.15.0
Hersteller-Advisory: GHSA-cjxc-rf3w-gjx2
Behoben in: 1.15.1
Gemeldet: 18. Juli 2026
Zusammenfassung
VoidAuth prueft den zweiten Faktor an einem eigenen Endpunkt, der weder einen Zaehler je Konto noch eine Sperre nach mehreren Fehlversuchen kennt. Die einzige Bremse ist eine globale Ratenbegrenzung, die an der Adresse des Aufrufers haengt. Die Anwendung vertraut dabei dem Proxy-Header, weshalb die Adresse aus dem ersten Eintrag von X-Forwarded-For stammt, den der Aufrufer selbst setzt. Wer diesen Eintrag bei jeder Anfrage aendert, bekommt jedes Mal einen frischen Zaehler und reicht beliebig viele Codes ein. Da die Pruefung ein Zeitfenster von einem Schritt zulaesst, sind jederzeit drei Codes gueltig, womit im Mittel etwa 333.000 Versuche genuegen.
Ursache
POST /api/interaction/totp prueft den zweiten Faktor ueber validateTOTP, das ein Fenster von einem Schritt erlaubt und keinen Zaehler fuer Fehlversuche fuehrt (server/db/totp.ts:75-91). Der zugehoerige Handler ergaenzt keine Sperre je Konto (server/routes/interaction.ts:906). Die einzige Bremse sind standardRateLimit und sensitiveRateLimit, beide an der voreingestellten Adresse req.ip ausgerichtet (server/util/rateLimit.ts:7-23). Weil app.enable('trust proxy') gesetzt ist, entspricht req.ip dem ersten, vom Aufrufer gelieferten Eintrag aus X-Forwarded-For (server/cli/server.ts:36). Die Zugangspruefung checkPrivilegedForTotpValidate verlangt lediglich einen abgeschlossenen ersten Faktor, sodass der Endpunkt mit einer reinen Passwort-Sitzung erreichbar ist.
Proof of Concept
# Angreifer kennt das Passwort des Opfers und hat den ersten Faktor bestanden.
for i in $(seq 0 999999); do
curl -s https://voidauth.example/api/interaction/totp \
-H "X-Forwarded-For: 10.0.$((RANDOM%255)).$((RANDOM%255))" \
-H 'Content-Type: application/json' \
-b "$SESSION" \
--data "{\"code\":\"$(printf '%06d' $i)\"}"
done
# Jede Anfrage traegt eine neue Adresse und damit einen frischen Zaehler.
# Drei Codes sind jederzeit gueltig, im Mittel genuegen rund 333.000 Versuche.
Nicht betroffen ist ein Aufbau, bei dem ein Reverse-Proxy X-Forwarded-For mit der echten Adresse des Klienten ueberschreibt, statt daran anzuhaengen.
Auswirkung
- Aushebelung der Mehrfaktor-Anmeldung fuer jedes Konto, das einen TOTP-Authentikator eingerichtet hat.
- Vollstaendige angemeldete Sitzung fuer einen Angreifer, der nur das Passwort des Opfers besitzt.
- Betroffen ist die Voreinstellung, sowohl bei direktem Netzzugriff als auch hinter jedem Proxy, der an
X-Forwarded-Foranhaengt, was dem ueblichen nginx-Muster entspricht. - Kein Hinweis fuer das Opfer, da keine Sperre und kein Fehlversuchszaehler existiert.
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.
