Mermaid's default configuration allows injecting CSS that applies outside of the Mermaid diagram via the fontFamily, themeCSS, and altFontFamily configuration options.
Live demo: mermaid.live
Example code:
%%{init: {"fontFamily": "x;a{b} :not(&){background:green !important} c{d}"}}%%
flowchart LR
A --> B
The injected CSS exploits stylis's & (scope reference) handling. :not(&) escapes the #mermaid-xxx automatic scoping, applying styles to all page elements. Global at-rules (@font-face, @keyframes, @counter-style) are also injectable as stylis hoists them to top level.
This allows page defacement and DOM attribute exfiltration via CSS :has() selectors.
If you can't upgrade mermaid, you can set the secure config value in the mermaid config to avoid allowing diagrams to modify fontFamily, themeCSS, altFontFamily, and themeVariables.
Setting "securityLevel": "sandbox" will also prevent this.
Reported by @zsxsoft on behalf of @KeenSecurityLab
No EPSS score in this advisory JSON.
| Base score | Version | Severity | Vector |
|---|---|---|---|
| 5.3 | 4.0 | — |
|
| Type | Value |
|---|---|
| GHSA | GHSA-87f9-hvmw-gh4p ↗ |
| CVE | CVE-2026-41159 ↗ |
| CWE id | Name |
|---|---|
| CWE-94 | Improper Control of Generation of Code ('Code Injection') |
Vulnerable version ranges and first patched releases as published by GitHub.
| Ecosystem | Package | Vulnerable range | First patched | Vulnerable functions |
|---|---|---|---|---|
| npm | mermaid | >= 11.0.0-alpha.1, <= 11.14.0 | 11.15.0 | — |
| npm | mermaid | <= 10.9.5 | 10.9.6 | — |