mermaid-js/mermaid · Security
Mermaid: Improper sanitization of `classDefs` in diagrams leads to CSS injection
- GHSA ID
- GHSA-xcj9-5m2h-648r
- CVE ID
- CVE-2026-41148
- Severity
- medium
- Published
- Updated
- CVSS v4
- 5.3 · CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:L/VA:N/SC:L/SI:L/SA:L
Description
Details
The state diagram and any other diagram type that routes user-controlled style strings through createCssStyles parser for Mermaid v11.14.0 and earlier captures classDef values with an unrestricted regex:
// packages/mermaid/src/diagrams/state/parser/stateDiagram.jison:83
<CLASSDEFID>[^\n]* { this.popState(); return 'CLASSDEF_STYLEOPTS' }
The value passes unsanitized through addStyleClass() -> createCssStyles() -> style.innerHTML (mermaidAPI.ts:418). A } in the value closes the generated CSS selector, and everything after becomes a new CSS rule on the page.
PoC
stateDiagram-v2
classDef x }*{ background-image: url("http://media.giphy.com/media/SggILpMXO7Xt6/giphy.gif")}
Patches
This has been patched in:
- v11.15.0 (see e9b0f34d8d82a6260077764ee45e1d7d90957a0f)
- v10.9.6 (see 8fead23c59166b7bab6a39eac81acebee2859102)
Workarounds
Setting "securityLevel": "sandbox" will prevent this, by rendering the mermaid diagram in a sandboxed <iframe>.
Impact
Enables page defacement, user tracking via url() callbacks, and DOM attribute exfiltration via CSS :has() selectors.
CWEs
- CWE-94 · Improper Control of Generation of Code ('Code Injection')
References
- https://github.com/mermaid-js/mermaid/security/advisories/GHSA-xcj9-5m2h-648r ↗
- https://github.com/mermaid-js/mermaid/commit/8fead23c59166b7bab6a39eac81acebee2859102 ↗
- https://github.com/mermaid-js/mermaid/commit/e9b0f34d8d82a6260077764ee45e1d7d90957a0f ↗
- https://github.com/mermaid-js/mermaid/releases/tag/mermaid%4011.15.0 ↗
- https://github.com/mermaid-js/mermaid/releases/tag/v10.9.6 ↗
- https://mermaid.js.org/config/schema-docs/config.html#securitylevel ↗
- https://nvd.nist.gov/vuln/detail/CVE-2026-41148 ↗
- https://github.com/advisories/GHSA-xcj9-5m2h-648r ↗