A security audit by ProjectDiscovery's Neo agent uncovered five CVEs in Markdown Preview Enhanced, a VS Code extension with roughly 9.5 million installs. A WaveDrom diagram block could trigger JavaScript execution via eval() inside the preview webview, chaining through an unvalidated postMessage dispatcher to an arbitrary file write on disk (CVE-2026-50733). Further auditing found a VM sandbox escape in workspace config files (CVE-2026-54566) giving direct OS command execution, a stored XSS via unsanitized head.html injection (CVE-2026-54701), and two shared infrastructure flaws in the command dispatcher and file-write API (CVE-2026-54702, CVE-2026-54703). All five were fixed across versions v0.8.28 through v0.8.30, with eval replaced by JSON parsing, vm.runInNewContext() and sval replaced with a WASM-isolated QuickJS engine, script stripping added to head.html injection, and a command allowlist plus URI pinning added to the dispatcher. Users are urged to update to v0.8.30 or later.
Table of contents
A WaveDrom block that runs as JavaScriptFrom a Markdown file to arbitrary file writeThe deeper audit: four more CVEsWhy this is a supply-chain problemHow Neo found itFixing this class of bugTimelineRelated readingQuestions this post answers
What CVEs were found in the Markdown Preview Enhanced VS Code extension and are they fixed?
Five CVEs were found: CVE-2026-50733 (WaveDrom eval code injection, fixed in v0.8.28), CVE-2026-54566 (VM sandbox escape in config.js/parser.js, fixed in v0.8.29), and CVE-2026-54701, CVE-2026-54702, CVE-2026-54703 (unsanitized head.html XSS, blind command dispatch, and arbitrary file write, all fixed in v0.8.30). Updating to v0.8.30 or later resolves all five. Track disclosed extension CVEs like these on daily.dev before deciding what to update.
How did a Markdown file lead to arbitrary file write in Markdown Preview Enhanced before the fix?
A WaveDrom diagram block's raw text was passed to window.eval(), letting a crafted Markdown file execute JavaScript inside the preview webview. That JavaScript reached the webview's postMessage channel, which dispatched any command name straight to VS Code's command system without validation, including an updateMarkdown command that wrote arbitrary content to any file:// URI with no path check. Developers securing editor extensions can follow chained exploit writeups like this on daily.dev.
Why is Node.js vm.runInNewContext() not safe for sandboxing untrusted code?
Because the sandbox object still lives in the host V8 realm, so its prototype chain leads back to the host's Function and process objects, letting an arrow-function IIFE recover this.constructor.constructor and call getBuiltinModule('child_process') to run arbitrary OS commands. Node's own documentation states vm is not a security mechanism; a real isolation boundary requires a separate engine such as QuickJS compiled to WebAssembly with its own heap. Anyone evaluating sandboxing options for untrusted code can weigh trade-offs like these on daily.dev.