Label Studio: Aufgabendaten führen Skript im Labeling-Editor aus

Der Filter für Aufgabendaten verbietet Ereignis-Attribute über eine Lückenliste, in der onfocusin und die SMIL-Elemente fehlen.

Advisory-ID: TP-2026-086
Produkt: Label Studio (Werkzeug zum Annotieren von Trainingsdaten, Django und React)
Schwachstellentyp: Stored Cross-Site-Scripting (CWE-79)
CVE: nicht beantragt
CVSS 3.1: 9.0 (Kritisch) · CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H
Betroffene Versionen: <= 1.23.0
Hersteller-Advisory: GHSA-f3gx-jhwx-w7pr
Behoben in: 1.23.1
Gemeldet: 07. Juni 2026

Zusammenfassung

Label Studio zeigt die zu annotierenden Aufgabendaten in den Objekt-Tags HyperText und Text als lebendes HTML an, damit Annotierende Formatierungen sehen. Der Server speichert diese Daten unverändert, die einzige Schranke ist ein Filter im Browser. Dieser Filter arbeitet mit einer Liste verbotener Ereignis-Attribute statt mit einer Liste erlaubter, und die Liste ist unvollständig. Über onfocusin, onanimationstart oder die SMIL-Elemente animate und set läuft Skript des Angreifers in der Herkunft der Anwendung. Es trifft jeden, der die Aufgabe öffnet, also andere Annotierende ebenso wie die Projektleitung, und von dort aus die gesamte API.

Ursache

Der Editor reicht den Aufgabenwert durch setRemoteValue() (web/libs/editor/src/tags/object/RichText/model.js:240), das ihn an sanitizeHtml() übergibt (web/libs/editor/src/utils/html.js:520), und schreibt das Ergebnis mit dangerouslySetInnerHTML in den DOM (RichText/view.jsx:570) oder in ein iframe mit srcDoc, dessen Sandbox allow-same-origin und allow-scripts zugleich trägt (:591). Dieser Filter ist die einzige Schranke, denn der Server legt die Aufgabendaten unverändert ab, was ein Abruf von /api/tasks/<id>/ bestätigt. Die Prüfung besteht aus einer Liste verbotener on-Attribute und der Tags script und iframe (html.js:553-639), nicht aus einer Liste erlaubter Elemente. In der Liste fehlen onfocusin, onanimationstart und die ontouch-Familie, und die SMIL-Elemente animate und set sind gar nicht erfasst. Damit ist der Fund eine Umgehung des Fixes aus GHSA-6xv9-957j-qfhg, der genau diese Liste eingeführt hatte.

Proof of Concept

# Aufgabe mit praeparierten Daten anlegen (Rolle: Annotator genuegt)
POST /api/projects/<id>/import
[{"text": "<svg><set attributeName=onbegin value=alert(document.domain) />"}]

# Variante ueber ein nicht gelistetes Ereignis-Attribut
[{"text": "<p onfocusin=alert(document.domain) tabindex=0 autofocus>x</p>"}]

# Opfer oeffnet die Aufgabe im Labeling-Editor -> Skript laeuft

Beide Nutzlasten überstehen sanitizeHtml(), weil die Liste nur bestimmte on-Attribute kennt und SMIL nicht berücksichtigt. Im iframe-Zweig hilft die Sandbox nicht, da sie allow-same-origin und allow-scripts gemeinsam setzt und das Dokument damit in der Herkunft der Anwendung läuft.

Auswirkung

  • Skriptausführung in der Herkunft der Anwendung bei jedem Nutzer, der die präparierte Aufgabe im Editor öffnet.
  • Rechteausweitung vom Annotator zur Projektleitung oder zur Administration, sobald eine dieser Rollen dieselbe Aufgabe prüft, was der vorgesehene Arbeitsablauf ist.
  • Zugriff auf die gesamte REST-API im Namen des Opfers, einschliesslich der Projekte, der Annotationen und der hinterlegten Speicher-Zugangsdaten.
  • Dieselbe Lücke in weiteren Senken desselben Filters, etwa im html-Attribut von Choice (Choice.jsx:214) und Label (Label.jsx:319).

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.