{"id":"GHSA-87f9-hvmw-gh4p","summary":"Mermaid: Improper sanitization of configuration leads to CSS injection","details":"### Impact\n\nMermaid's default configuration allows injecting CSS that applies outside of the Mermaid diagram via the `fontFamily`, `themeCSS`, and `altFontFamily` configuration options.\n\nLive demo: [mermaid.live](https://mermaid.live/edit#pako:eNpNjktLxDAUhf9KvFBR6JS-60QQfODKlUvJ5k6TtsEmKTHFGUP-u-mI6Nmdy3fOPR56wwVQSBIvtXSUeAaD0e4ZlZxPDChhcLxFfwiEauOuLq_9Afv30ZpVczpaITS5kGox1qF2gfSeBwYhJAnThAyz-ewntI68vG5-0z3Z7e7IA9OQwmglB-rsKlJQwircLPgNZeAmocTPAi4GXGfHgOkQYwvqN2PUbzJuGSegA84f0a0LRyeeJI4W_xChubCPcbQD2pwbgHo4Aq2aKmvbqq3zoiu7pizqFE6RybN9VFfFY1HWXRVS-Dr_zLObrt7_V_gGGXZlGg)\n\nExample code:\n\n```\n%%{init: {\"fontFamily\": \"x;a{b} :not(&){background:green !important} c{d}\"}}%%\nflowchart LR\n    A --\u003e B\n```\n\nThe 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.\n\nThis allows page defacement and DOM attribute exfiltration via CSS `:has()` selectors.\n\n### Patches\n\n- [v11.15.0](https://github.com/mermaid-js/mermaid/releases/tag/mermaid%4011.15.0) (see [64769738d5b59211e1decb471ffbaca8afec51aa](https://github.com/mermaid-js/mermaid/commit/64769738d5b59211e1decb471ffbaca8afec51aa))\n- [v10.9.6](https://github.com/mermaid-js/mermaid/releases/tag/v10.9.6) (see [a9d9f0d8eb790349121508688cd338253fd80d76](https://github.com/mermaid-js/mermaid/commit/a9d9f0d8eb790349121508688cd338253fd80d76))\n\n### Workarounds\n\nIf you can't upgrade mermaid, you can set the [`secure`](https://mermaid.js.org/config/schema-docs/config.html#secure) config value in the mermaid config to avoid allowing diagrams to modify `fontFamily`, `themeCSS`, `altFontFamily`, and `themeVariables`.\n\nSetting [`\"securityLevel\": \"sandbox\"`](https://mermaid.js.org/config/schema-docs/config.html#securitylevel)  will also prevent this.\n\n### Credits\n\nReported by @zsxsoft on behalf of @KeenSecurityLab","aliases":["CVE-2026-41159"],"modified":"2026-05-11T19:49:39.861570Z","published":"2026-05-11T19:37:00Z","database_specific":{"github_reviewed_at":"2026-05-11T19:37:00Z","cwe_ids":["CWE-94"],"nvd_published_at":null,"severity":"MODERATE","github_reviewed":true},"references":[{"type":"WEB","url":"https://github.com/mermaid-js/mermaid/security/advisories/GHSA-87f9-hvmw-gh4p"},{"type":"WEB","url":"https://github.com/mermaid-js/mermaid/commit/64769738d5b59211e1decb471ffbaca8afec51aa"},{"type":"WEB","url":"https://github.com/mermaid-js/mermaid/commit/a9d9f0d8eb790349121508688cd338253fd80d76"},{"type":"PACKAGE","url":"https://github.com/mermaid-js/mermaid"},{"type":"WEB","url":"https://github.com/mermaid-js/mermaid/releases/tag/mermaid%4011.15.0"},{"type":"WEB","url":"https://github.com/mermaid-js/mermaid/releases/tag/v10.9.6"}],"affected":[{"package":{"name":"mermaid","ecosystem":"npm","purl":"pkg:npm/mermaid"},"ranges":[{"type":"SEMVER","events":[{"introduced":"11.0.0-alpha.1"},{"fixed":"11.15.0"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/05/GHSA-87f9-hvmw-gh4p/GHSA-87f9-hvmw-gh4p.json","last_known_affected_version_range":"\u003c= 11.14.0"}},{"package":{"name":"mermaid","ecosystem":"npm","purl":"pkg:npm/mermaid"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"10.9.6"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/05/GHSA-87f9-hvmw-gh4p/GHSA-87f9-hvmw-gh4p.json","last_known_affected_version_range":"\u003c= 10.9.5"}}],"schema_version":"1.7.5","severity":[{"type":"CVSS_V4","score":"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"}]}