
MISP <= 2.5.27 - Gespeichertes Cross-Site Scripting via Workflow Engine (doT.js Template Injection)
MISP <= 2.5.27 – Stored Cross‑Site Scripting über die Workflow‑Engine (doT.js Template Injection)
Entdeckt von Franck FERMAN
Übersicht – Grundursache – Angriffskette – Struktur – Nutzung – Behebung – Referenzen
CVE‑2025‑67906 (GCVE‑1‑2025‑0031) ist eine Stored Cross‑Site Scripting (XSS)‑Schwachstelle in MISP (Malware Information Sharing Platform) bis einschließlich Version 2.5.27.
Die Schwachstelle befindet sich in app/View/Elements/Workflows/executionPath.ctp, der Workflow‑Ausführungspfad‑Ansicht. Das name‑Feld von Workflow‑Triggern wird ohne serverseitige Bereinigung in der Datenbank gespeichert und anschließend – ohne HTML‑Escaping – über die doT.js‑Template‑Engine in das DOM eingefügt. Ein authentifizierter Angreifer kann beliebiges HTML/JavaScript injizieren, das in der Browsersitzung jedes Benutzers ausgeführt wird, der den manipulierten Workflow aufruft.
Da das Payload in der Datenbank gespeichert und bei jedem Seitenaufruf gerendert wird, ist das XSS persistent – es übersteht Seitenaktualisierungen, betrifft mehrere Benutzer und bleibt bestehen, bis der Workflow explizit gelöscht wird.
Entdeckung: Diese Schwachstelle wurde von Franck FERMAN identifiziert und verantwortungsvoll offengelegt.
Für diese Schwachstelle liegen mehrere CVSS‑Bewertungen vor:
| Quelle | Punktzahl | Schweregrad | Vektor |
|---|---|---|---|
| NIST NVD | 9.0 | Kritisch | CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H |
| GCVE (CIRCL) | 7.1 | Hoch | CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:A/VC:H/VI:N/VA:N/SC:H/SI:H/SA:H |
| CNA (MITRE) | 5.4 | Mittel | CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N |
Die Abweichung der Bewertungen spiegelt unterschiedliche Einschätzungen der Auswirkungen wider. Die NIST‑NVD‑Bewertung (9.0) berücksichtigt die volle Auswirkung auf Vertraulichkeit, Integrität und Verfügbarkeit, da das XSS‑Payload mit den Sitzungsrechten des Opfers ausgeführt wird und somit eine Exfiltration auf Admin‑Ebene sowie die Manipulation von Workflows ermöglicht. Die CNA‑Bewertung (5.4) geht von einer eingeschränkten C/I‑Auswirkung eines generischen XSS aus. Der GCVE‑CVSS‑4.0‑Wert (7.1) führt Angriffsanforderungen (Privileg) und aktive Benutzerinteraktion als Modifikatoren ein.
Der Scope wird bei allen Bewertungen als Changed eingestuft, da das Payload des Angreifers (über die MISP‑API injiziert) in einem anderen Sicherheitskontext ausgeführt wird (der Browsersitzung des Opfers).
Die Workflow‑Engine von MISP erlaubt authentifizierten Benutzern, Workflows über die REST‑API zu erstellen und zu bearbeiten. Das Datenmodell des Workflows enthält eine trigger‑Komponente mit einem name‑Feld. Dieses Feld wird:
doT.js ist eine schnelle JavaScript‑Template‑Engine. Sie verwendet {{= }} für die Interpolation, die standardmäßig kein HTML escaped. Der MISP‑Workflow‑Editor nutzt doT.js, um Trigger‑Metadaten (einschließlich des name‑Felds) in das DOM zu rendern. Enthält das name‑Feld HTML wie ``, fügt die Template‑Engine es als rohes HTML ein, und der Browser führt das eingebettete JavaScript aus.
Die Behebung erfordert entweder:
kodierte Ausgabesyntax{{! }}`, die den Wert HTML‑escapedPOST /workflows/edit/{id}
{
"Workflow": {
"id": "1",
"data": "{\"1\":{\"data\":{\"name\":\"\"}}}"
}
}
Der name‑Wert im data‑JSON‑Feld ist der Injektionspunkt. Der gesamte Workflow‑Graph wird als JSON‑String im Request‑Body serialisiert.
Die Schwachstelle wird durch die architektonische Entscheidung verstärkt, eine clientseitige Template‑Engine (doT.js) für die visuelle Darstellung des Workflow‑Editors zu verwenden. Der Workflow‑Editor ist eine grafische Drag‑and‑Drop‑Oberfläche, in der jeder Trigger/Aktion als visueller Block dargestellt wird. Das name‑Feld des Triggers wird als Beschriftung innerhalb dieser grafischen Blöcke gerendert.
doT.js erstellt die visuellen Komponenten, indem es HTML‑Strings aus Templates generiert und in das DOM einfügt. Die Interpolationssyntax {{= }} erzeugt unescapierte Ausgabe – jede in das Template interpolierte Daten wird als Markup behandelt, nicht als Text. Würde dasselbe name‑Feld über element.textContent (das Eingabe als Klartext behandelt) oder über doT.jseigene kodierte Ausgabesyntax{{! }}` gerendert, wäre unabhängig vom Eingabeinhalt kein XSS möglich.
Die Angriffsfläche besteht genau deshalb, weil:
{{= }}) verwendet – aus Performance‑Gründenname‑Feld gespeicherte String vom Browser als HTML interpretiert wirdDies ist ein häufiges Schwachstellenmuster in Webanwendungen, die clientseitige Template‑Engines für interaktive visuelle Oberflächen verwenden: Die Notwendigkeit umfangreichen Renderings erzeugt eine implizite Vertrauensbeziehung zwischen dem Template und seinen Datenquellen, und jede unbereinigte Benutzereingabe, die das Template erreicht, wird zu ausführbarem Code.
<script>Ein roher <script>‑Tag, der über Template‑Interpolation injiziert wird, wird in diesem Kontext typischerweise nicht ausgeführt. Browser führen <script>‑Elemente nicht aus, die nach dem initialen Seitenparsing (via innerHTML oder ähnlichem) in das DOM eingefügt werden. Event‑Handler‑Attribute wie onerror, onload oder onmouseover auf HTML‑Elementen umgehen diese Einschränkung, da sie Inline‑JavaScript auslösen, sobald der Browser die Attribute des Elements verarbeitet – unabhängig davon, wie das Element eingefügt wurde.
Der <img src="https://raw.githubusercontent.com/franckferman/cve-2025-67906/HEAD/x" onerror="...">‑Vektor wird bevorzugt, weil:
src="x" einen sofortigen Ladefehler garantiert und damit onerror ohne Benutzerinteraktion auslöstscript‑src‑Einschränkungen umgeht, die Inline‑<script>‑Tags blockieren, da die Ausführung über einen Event‑Handler auf einem Nicht‑Skript‑Element erfolgt