Plane: Mandantenübergreifendes Stored XSS im Intake ermöglicht Kontoübernahme

Ein beliebiges Konto der Instanz pflanzt ohne jede Projektmitgliedschaft HTML in fremde Intake-Queues und übernimmt nach einem Klick dauerhaft das Konto des Betrachters.

Advisory-ID: TP-2026-079
Produkt: Plane (Open-Source-Projektmanagement für Issues, Zyklen und Module)
Schwachstellentyp: Mandantenübergreifendes Stored Cross-Site-Scripting mit fehlender Autorisierung (CWE-79, CWE-862)
CVE: CVE-2026-104979
CVSS 3.1: 8.7 (Hoch) · CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:N
Betroffene Versionen: <= 1.3.1
Hersteller-Advisory: GHSA-hh2r-3hwp-mvq3
Behoben in: 1.4.0
Gemeldet: 16. Mai 2026

Zusammenfassung

Plane ist eine Open-Source-Anwendung für Projektmanagement, in der mehrere Workspaces auf derselben Instanz getrennt voneinander arbeiten. Die öffentliche Intake-API, über die Außenstehende Feedback zu einem veröffentlichten Projekt einreichen, speichert das mitgelieferte HTML ungeprüft und verlangt dabei nur ein angemeldetes Konto, keine Mitgliedschaft im Zielprojekt. Ein frisch registrierter Nutzer ohne jede Zugehörigkeit kann so einen präparierten Link in die Intake-Queue eines fremden Workspaces legen, den Projektmitglieder im Rahmen ihrer normalen Arbeit sichten. Ein Parserfehler in der Link-Erweiterung des Editors lässt den Link beim Klick als JavaScript in der Sitzung des Betrachters laufen, der daraufhin ein langlebiges API-Token erzeugt und abfließen lässt. Das Token überdauert Abmeldung und Passwortwechsel, womit aus einem einzelnen Klick eine dauerhafte Kontoübernahme wird.

Ursache

IntakeIssuePublicViewSet.create schreibt das Feld description_html direkt über Issue.objects.create in die Datenbank und umgeht damit die Sanitisierung, die der reguläre Serializer über validate_html_content durchführt (apps/api/plane/space/views/intake.py:145-152). Der Endpunkt erbt die Standardberechtigung IsAuthenticated ohne Prüfung auf Workspace- oder Projektmitgliedschaft, sodass jedes Konto der Instanz in jedes Projekt mit aktiviertem Intake schreibt. Die Link-Erweiterung des Editors prüft gefährliche Protokolle mit href.toLowerCase().startsWith(...) und entfernt führende Steuerzeichen nicht, während der WHATWG-Parser des Browsers sie entfernt, sodass ein mit Tabulator präfigiertes javascript: beide Prüfungen passiert und im DOM als ausführbares Schema ankommt (packages/editor/src/core/extensions/custom-link/extension.tsx:156-180). Der zugehörige Klick-Handler ruft window.open(href, target) mit dem vom Angreifer gesetzten target auf, und _self umgeht die Browsersperre für javascript: in neuen Tabs (packages/editor/src/core/extensions/custom-link/helpers/clickHandler.ts:43). Die Instanz liefert auf keiner Route einen Content-Security-Policy-Header aus, und POST /api/users/api-tokens/ gibt ein Token im Klartext ohne Alt-Passwort-Prüfung, ohne Sitzungsbindung und ohne vorgegebenen Ablauf zurück, womit der eingeschleuste Code den Zugriff dauerhaft verankert.

Proof of Concept

POST /api/public/anchor/<anchor>/intakes/<intake_id>/intake-issues/
Cookie: <Sitzung eines frisch registrierten Kontos ohne Mitgliedschaft>

{"issue": {"name": "Feedback",
           "description_html": "<p><a target=\"_self\" href=\"\tjavascript:...\">Anhang.pdf</a></p>"}}

-> HTTP 200, das HTML liegt unveraendert in der Datenbank
-> ein Projektmitglied oeffnet die Intake-Ansicht und klickt den Link
-> window.open("\tjavascript:...", "_self") fuehrt den Code in der Sitzung des Opfers aus

Der Tabulator vor javascript: überlebt die Protokollprüfung des Editors, wird vom URL-Parser des Browsers aber entfernt. Der ausgeführte Code legt über die Token-API ein langlebiges API-Token an und sendet es an einen vom Angreifer kontrollierten Server.

Auswirkung

  • Dauerhafte Übernahme jedes Kontos, dessen Inhaber den eingeschleusten Link in der Intake-Queue anklickt.
  • Zugriff über ein gestohlenes API-Token, das Abmeldung, Passwortwechsel und Sitzungsrotation überdauert.
  • Mandantenübergreifender Angriff: jedes Konto der Instanz erreicht jedes Projekt mit aktiviertem Intake, auch ohne jede Mitgliedschaft.
  • Lesen und Verändern aller Daten in den Workspaces des Opfers mit dessen Rechten.

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.