{"id":"CVE-2026-84992","aliases":["EUVD-2026-83198","GHSA-3rm2-h79c-8qw6"],"status":"published","title":"md-editor-v3: XSS via fenced-code language rendering bypass","description":"md-editor-v3 is a Markdown editor for Vue 3 developed in JSX and TypeScript. Prior to 6.5.4, MdPreview's useMarkdownIt() highlight callback in packages/MdEditor/layouts/Content/composition/useMarkdownIt.ts inserts a fenced-code language value into class and language HTML attributes without escaping or consistently quoting it. Both highlighted and non-highlighted rendering paths reach this return value, while XSSPlugin filters only existing html_block and html_inline tokens before rendering and therefore cannot inspect the renderer-generated HTML. An attacker who can supply Markdown can use crafted fenced-code metadata to execute JavaScript in the application origin when a victim renders it, including as stored cross-site scripting when the host persists the Markdown. This issue is fixed in version 6.5.4","severity":{"version":"3.1","score":6.1,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N","level":"medium","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-11","score":0.00327,"percentile":0.26102,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-79"],"published":"2026-09-18T17:10:08Z","modified":"2026-10-28T02:30:44Z","fixes":[{"ecosystem":"npm","package":"md-editor-v3","fixed_in":["6.5.4"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"npm","package":"md-editor-v3","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"last_affected":"6.5.3"},{"fixed":"6.5.4"}]}]},{"source":"osv","ecosystem":"npm","package":"md-editor-v3","ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"6.5.4"}]}]}],"products":[{"vendor":"imzbf","product":"md-editor-v3"}],"references":[{"url":"https://github.com/imzbf/md-editor-v3/security/advisories/GHSA-3rm2-h79c-8qw6","tags":["x_refsource_CONFIRM","exploit","advisory","web"]},{"url":"https://github.com/imzbf/md-editor-v3/commit/2c07360420e74087f5bc63032ab155d93e0a0b10","tags":["x_refsource_MISC","fix","web"]},{"url":"https://github.com/imzbf/md-editor-v3/releases/tag/v6.5.4","tags":["x_refsource_MISC","web"]},{"url":"https://github.com/advisories/GHSA-3rm2-h79c-8qw6"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/84xxx/CVE-2026-84992.json","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-84992","tags":["advisory"]},{"url":"https://github.com/imzbf/md-editor-v3","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2026-84992","title":"md-editor-v3: XSS via fenced-code language rendering bypass","description":"md-editor-v3 is a Markdown editor for Vue 3 developed in JSX and TypeScript. Prior to 6.5.4, MdPreview's useMarkdownIt() highlight callback in packages/MdEditor/layouts/Content/composition/useMarkdownIt.ts inserts a fenced-code language value into class and language HTML attributes without escaping or consistently quoting it. Both highlighted and non-highlighted rendering paths reach this return value, while XSSPlugin filters only existing html_block and html_inline tokens before rendering and therefore cannot inspect the renderer-generated HTML. An attacker who can supply Markdown can use crafted fenced-code metadata to execute JavaScript in the application origin when a victim renders it, including as stored cross-site scripting when the host persists the Markdown. This issue is fixed in version 6.5.4","status":"published","published":"2026-09-18T17:10:08.497Z","modified":"2026-09-18T18:06:19.593Z","cvss":[{"version":"3.1","score":6.1,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N","level":"medium","assessor":"cna"}],"cwes":["CWE-79"],"updated_at":"2026-11-02T14:20:08.734143Z"}],"euvd":[{"id":"EUVD-2026-83198","description":"md-editor-v3 is a Markdown editor for Vue 3 developed in JSX and TypeScript. Prior to 6.5.4, MdPreview's useMarkdownIt() highlight callback in packages/MdEditor/layouts/Content/composition/useMarkdownIt.ts inserts a fenced-code language value into class and language HTML attributes without escaping or consistently quoting it. Both highlighted and non-highlighted rendering paths reach this return value, while XSSPlugin filters only existing html_block and html_inline tokens before rendering and therefore cannot inspect the renderer-generated HTML. An attacker who can supply Markdown can use crafted fenced-code metadata to execute JavaScript in the application origin when a victim renders it, including as stored cross-site scripting when the host persists the Markdown. This issue is fixed in version 6.5.4","status":"published","published":"2026-09-18T17:10:08Z","modified":"2026-09-18T18:06:19Z","cvss":[{"version":"3.1","score":6.1,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N","level":"medium"}],"updated_at":"2026-11-02T17:28:07.943492Z"}],"ghsa":[{"id":"GHSA-3rm2-h79c-8qw6","title":"md-editor-v3: XSS via fenced-code language rendering bypass","description":"### Summary\n`MdPreview` interpolates a fenced-code language into HTML attributes without escaping it. A crafted info string therefore executes JavaScript even when the shipped `XSSPlugin` is enabled.\n\n### Details\n`useMarkdownIt()` (`packages/MdEditor/layouts/Content/composition/useMarkdownIt.ts:206`) registers a `highlight` callback whose final return inserts `language` into both `class=\"language-${language}\"` and an unquoted `language=${language}` attribute without escaping. Both highlighting paths reach this return. `XSSPlugin()` filters only existing `html_block` and `html_inline` tokens before rendering, so it cannot inspect this renderer-generated HTML.\n\n### PoC\nThe Vue application enables the shipped `XSSPlugin` and renders attacker-controlled Markdown. `noHighlight: true` only makes reproduction deterministic; the default highlighting path reaches the same unsafe return. Use this as `src/main.js`:\n\n```js\nimport { createApp, h } from 'vue';\nimport { MdPreview, XSSPlugin, config } from 'md-editor-v3';\n\nconfig({ markdownItPlugins: p =\u003e [...p, { type: 'xss', plugin: XSSPlugin, options: {} }] });\nconst markdown = '```x\"\u003e\u003cdetails/open/ontoggle=alert(document.domain)\u003e\\nSAFE\\n```';\ncreateApp({ render: () =\u003e h(MdPreview,\n  { editorId: 'poc', modelValue: markdown, noHighlight: true })\n}).mount('#app');\n```\n\nCreate and run the app, replacing `src/main.js` when indicated:\n\n```sh\nnpm create vite@latest poc -- --template vue\ncd poc\nnpm install\nnpm install md-editor-v3@6.5.3\n# Replace src/main.js with the code above.\nnpm run dev\n```\n\nOpening the displayed URL automatically shows the application hostname in an alert.\n\n### Impact\nAn attacker who can supply Markdown can execute JavaScript in the application origin when a victim renders it. If the host stores that Markdown, this becomes stored XSS.\n\n### Suggested fix\nEscape `language` with `md.utils.escapeHtml` before interpolation and quote the `language` attribute. Add this payload and the raw control as regression tests with `XSSPlugin` enabled.","status":"published","published":"2026-09-18T17:17:36Z","modified":"2026-09-18T17:17:38Z","cvss":[{"version":"3.1","score":6.1,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N","level":"medium"}],"cwes":["CWE-79"],"updated_at":"2026-11-02T14:41:19.455935Z"}],"nvd":[{"id":"CVE-2026-84992","description":"md-editor-v3 is a Markdown editor for Vue 3 developed in JSX and TypeScript. Prior to 6.5.4, MdPreview's useMarkdownIt() highlight callback in packages/MdEditor/layouts/Content/composition/useMarkdownIt.ts inserts a fenced-code language value into class and language HTML attributes without escaping or consistently quoting it. Both highlighted and non-highlighted rendering paths reach this return value, while XSSPlugin filters only existing html_block and html_inline tokens before rendering and therefore cannot inspect the renderer-generated HTML. An attacker who can supply Markdown can use crafted fenced-code metadata to execute JavaScript in the application origin when a victim renders it, including as stored cross-site scripting when the host persists the Markdown. This issue is fixed in version 6.5.4","status":"published","published":"2026-09-18T18:17:17.277Z","modified":"2026-09-24T21:25:27.05Z","cvss":[{"version":"3.1","score":6.1,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N","level":"medium","assessor":"secondary"}],"cwes":["CWE-79"],"updated_at":"2026-11-02T14:12:50.043898Z"}],"osv":[{"id":"CVE-2026-84992","title":"md-editor-v3: XSS via fenced-code language rendering bypass","description":"md-editor-v3 is a Markdown editor for Vue 3 developed in JSX and TypeScript. Prior to 6.5.4, MdPreview's useMarkdownIt() highlight callback in packages/MdEditor/layouts/Content/composition/useMarkdownIt.ts inserts a fenced-code language value into class and language HTML attributes without escaping or consistently quoting it. Both highlighted and non-highlighted rendering paths reach this return value, while XSSPlugin filters only existing html_block and html_inline tokens before rendering and therefore cannot inspect the renderer-generated HTML. An attacker who can supply Markdown can use crafted fenced-code metadata to execute JavaScript in the application origin when a victim renders it, including as stored cross-site scripting when the host persists the Markdown. This issue is fixed in version 6.5.4","status":"published","published":"2026-09-18T17:10:08.497Z","modified":"2026-10-28T02:30:44.874214905Z","cvss":[{"version":"3.1","score":6.1,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N","level":"medium"}],"cwes":["CWE-79"],"updated_at":"2026-11-02T15:45:18.482949Z"},{"id":"GHSA-3rm2-h79c-8qw6","title":"md-editor-v3: XSS via fenced-code language rendering bypass","description":"### Summary\n`MdPreview` interpolates a fenced-code language into HTML attributes without escaping it. A crafted info string therefore executes JavaScript even when the shipped `XSSPlugin` is enabled.\n\n### Details\n`useMarkdownIt()` (`packages/MdEditor/layouts/Content/composition/useMarkdownIt.ts:206`) registers a `highlight` callback whose final return inserts `language` into both `class=\"language-${language}\"` and an unquoted `language=${language}` attribute without escaping. Both highlighting paths reach this return. `XSSPlugin()` filters only existing `html_block` and `html_inline` tokens before rendering, so it cannot inspect this renderer-generated HTML.\n\n### PoC\nThe Vue application enables the shipped `XSSPlugin` and renders attacker-controlled Markdown. `noHighlight: true` only makes reproduction deterministic; the default highlighting path reaches the same unsafe return. Use this as `src/main.js`:\n\n```js\nimport { createApp, h } from 'vue';\nimport { MdPreview, XSSPlugin, config } from 'md-editor-v3';\n\nconfig({ markdownItPlugins: p =\u003e [...p, { type: 'xss', plugin: XSSPlugin, options: {} }] });\nconst markdown = '```x\"\u003e\u003cdetails/open/ontoggle=alert(document.domain)\u003e\\nSAFE\\n```';\ncreateApp({ render: () =\u003e h(MdPreview,\n  { editorId: 'poc', modelValue: markdown, noHighlight: true })\n}).mount('#app');\n```\n\nCreate and run the app, replacing `src/main.js` when indicated:\n\n```sh\nnpm create vite@latest poc -- --template vue\ncd poc\nnpm install\nnpm install md-editor-v3@6.5.3\n# Replace src/main.js with the code above.\nnpm run dev\n```\n\nOpening the displayed URL automatically shows the application hostname in an alert.\n\n### Impact\nAn attacker who can supply Markdown can execute JavaScript in the application origin when a victim renders it. If the host stores that Markdown, this becomes stored XSS.\n\n### Suggested fix\nEscape `language` with `md.utils.escapeHtml` before interpolation and quote the `language` attribute. Add this payload and the raw control as regression tests with `XSSPlugin` enabled.","status":"published","published":"2026-09-18T17:17:36Z","modified":"2026-09-18T17:30:08.398856654Z","cvss":[{"version":"3.1","score":6.1,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N","level":"medium"}],"cwes":["CWE-79"],"updated_at":"2026-11-02T15:46:36.092962Z"}]}}
