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.
stateDiagram-v2
classDef x }*{ background-image: url("http://media.giphy.com/media/SggILpMXO7Xt6/giphy.gif")}
This has been patched in:
Setting "securityLevel": "sandbox" will prevent this, by rendering the mermaid diagram in a sandboxed <iframe>.
Enables page defacement, user tracking via url() callbacks, and DOM attribute exfiltration via CSS :has() selectors.
{
"github_reviewed": true,
"github_reviewed_at": "2026-05-11T19:36:41Z",
"cwe_ids": [
"CWE-94"
],
"severity": "MODERATE",
"nvd_published_at": null
}