Context
The operator reported four DOMPurify Dependabot alerts after the overnight dependency update. Live default branch dev at ea54d5ff89eef87cdb3ade0a2f0e17fdf79ca7bf contains:
mermaid@11.17.2 → dompurify ^3.3.3 → 3.4.13 (already above the four advisory floors).
monaco-editor@0.56.0 → dompurify 3.4.8 (exact pin; vulnerable nested lock entry).
The four open alerts all name package-lock.json, transitive development dependency dompurify:
The alerts were created earlier and updated at 2026-09-05T00:49:36Z. This is the current affected dependency graph, not a claim that four advisories were newly published overnight.
The Problem
A dependency override can replace the installed nested npm package but cannot replace the sanitizer Monaco actually executes. The published Monaco distribution embeds its own DOMPurify copy.
Measured directly from the official monaco-editor-0.56.0.tgz:
esm/vs/base/browser/dompurify/dompurify.js carries DOMPurify 3.4.8.
esm/vs/base/browser/domSanitize.js imports that relative vendor module, not the npm dompurify package.
- The distributed
dev/vs/editor-ECyZhXSU.js and min/vs/editor-KLE6jdfb.js chunks also contain version 3.4.8.
- Neo's
src/main/addon/MonacoEditor.mjs#loadFiles loads node_modules/monaco-editor/min/vs directly.
Consequently, an npm-only override could make dependency scanners green while leaving the browser sanitizer unchanged.
This verifies affected-version presence, not a demonstrated XSS exploit in Neo. These advisories require specific hooks/configuration; no exploitability claim or blanket exemption is made here.
The Architectural Reality
DOMPurify is indirect but not absent from the editor: Monaco uses it for internal HTML/Markdown sanitization. The runtime source comes through VS Code's vendor copy. Upstream already reverted a dependency-only bump for this reason, and Monaco issue 5454 tracks the bundled-copy problem.
Registry verification on 2026-09-05: Monaco latest is 0.56.0, still pinned to 3.4.8. DOMPurify latest is 3.4.14; 3.4.13 meets all four listed advisory floors.
Existing root overrides in package.json addresses gray-matter/js-yaml, but that precedent does not alter already bundled JavaScript. No Engine API or ADR change is needed for a corrected upstream package.
The Fix
Current disposition: no corrected upstream distribution; a reproducible consumer-build candidate is now validated below. Keep the alerts visible until the selected production integration repairs both metadata and executed assets.
Upgrade the pinned Monaco package when its shipped editor assets and dependency metadata both contain patched DOMPurify, then regenerate the lockfile and verify the actual editor asset path.
If an earlier local remediation is required, it must be a reproducible Monaco build using patched DOMPurify at module resolution and a verified Neo loader/worker integration. That is a build integration choice, not a package-only override. Do not introduce minified-bundle surgery or an install-time patch as an implicit workaround.
Revalidation trigger: an upstream release/update on microsoft/monaco-editor#5454 or an explicitly selected local rebuild approach.
Contract Ledger Matrix
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback |
Docs |
Evidence |
| Monaco dependency + lock entries |
npm metadata and four advisories above |
no DOMPurify entry in an affected range |
retain visible alerts while upstream is unpatched |
package metadata |
clean install and complete dependency-tree inspection |
| shipped Monaco sanitizer |
vendor module and AMD chunks in published tarball |
executed sanitizer is patched, not only the lockfile |
no scanner-only exemption |
remediation receipt on this ticket |
inspect shipped assets; browser uses those assets |
| Neo Monaco loader |
src/main/addon/MonacoEditor.mjs#loadFiles |
editor and workers still load through the selected distribution |
observable load failure |
existing addon JSDoc if integration changes |
browser create/edit/worker and sanitized-hover smoke |
Acceptance Criteria
Out of Scope
Mermaid updates (its current sanitizer is already patched for these four alerts), replacing Monaco with another editor, unrelated dependency upgrades, and claiming exploitability from version matching alone.
Avoided Traps
- An override that replaces an unused npm copy while the browser keeps executing the embedded old copy.
- Downgrading Monaco to remove dependency metadata without checking its embedded sanitizer.
- Assuming a dependency labeled development cannot reach the browser.
- Editing third-party minified files manually.
Extended investigation — 2026-09-05
The published latest remains Monaco 0.56.0; next is 0.56.0-dev-20260625, whose metadata also pins DOMPurify 3.4.8. All four alerts remain open. Mermaid's installed 3.4.13 satisfies these four advisory floors.
Exposure in the inspected integration
The four advisories require, respectively: a prior custom Trusted Types policy on the reused instance; persistent setConfig() plus an allowlist-mutating attribute hook; custom-element handling plus an afterSanitizeElements policy; or IN_PLACE plus an element-removal hook. The shipped Monaco domSanitize.js builds per-call configuration, accepts string input, and does not configure those combinations. Its attribute predicate uses per-element keepAttr.
Executed the current Neo wrapper's AMD editor and JavaScript worker: diagnostics were empty; a custom HTML-capable Markdown hover removed event handlers and javascript: links, with no marker execution or page error. Separately instrumented the official ESM sanitizer: three exercised calls all used string input, no IN_PLACE, no custom-element configuration, no custom Trusted Types policy, and zero setConfig/clearConfig calls. This bounds the observed path; it does not certify every embedder or replace the dependency remediation.
Reproducible consumer-build candidate
A working alternative now exists. Using Monaco's official esbuild smoke-build pattern, compiled the published 0.56.0 ESM modules while resolving the vendor import in domSanitize.js to the official DOMPurify 3.4.14 ESM distribution. This substitutes a module at build time; no third-party source or minified bundle was edited.
- The esbuild metadata proves the actual
domSanitize.js → purify.es.mjs edge, with the old vendor module absent.
- Generated editor JavaScript, CSS, font and all five standard worker entry points.
- Browser candidate reports 3.4.14, boots the editor, reads its live model through the TypeScript worker, and passes the sanitized-hover smoke with zero page errors or failed asset responses.
- Two builds with esbuild 0.28.2 produce the same editor bundle: 4,483,078 bytes, SHA-256
d02e1a8915eeb1bb4a6d7dd0961e4f4855cbb583d3c9534cc4ad700153c57410.
This is an isolated candidate, not the shipped Neo runtime. Production adoption still needs a maintained asset-build entry, Neo loader/worker URL integration, a patched dependency/lock graph, and the existing real-wrapper lifecycle tests against those generated assets. The candidate carries a diagnostic version export that would not be part of the production API. No repository files or alert dispositions changed during these probes.
The complete remediation can therefore proceed through a consumer build if upstream publication remains delayed; the current installed package continues to need repair.
Related
Monaco bundled sanitizer issue, upstream reverted metadata-only bump, DOMPurify 3.4.14 release.
Decision Record impact: none.
Origin Session ID: cb7ccc74-b375-4785-9adf-df6d1112957b
Retrieval Hint: Monaco 0.56.0 DOMPurify 3.4.8 bundled copy override alert 222 186 164 155
Creation freshness: live latest-20 open issue and all-status recent A2A sweeps immediately before filing found no equivalent ticket or competing claim. All-state DOMPurify issue search was empty. Semantic queries returned unrelated older material, so current GitHub, registry metadata, and published package bytes are the evidence.
Context
The operator reported four DOMPurify Dependabot alerts after the overnight dependency update. Live default branch
devatea54d5ff89eef87cdb3ade0a2f0e17fdf79ca7bfcontains:mermaid@11.17.2 → dompurify ^3.3.3 → 3.4.13(already above the four advisory floors).monaco-editor@0.56.0 → dompurify 3.4.8(exact pin; vulnerable nested lock entry).The four open alerts all name
package-lock.json, transitive development dependencydompurify:The alerts were created earlier and updated at 2026-09-05T00:49:36Z. This is the current affected dependency graph, not a claim that four advisories were newly published overnight.
The Problem
A dependency override can replace the installed nested npm package but cannot replace the sanitizer Monaco actually executes. The published Monaco distribution embeds its own DOMPurify copy.
Measured directly from the official
monaco-editor-0.56.0.tgz:esm/vs/base/browser/dompurify/dompurify.jscarries DOMPurify 3.4.8.esm/vs/base/browser/domSanitize.jsimports that relative vendor module, not the npmdompurifypackage.dev/vs/editor-ECyZhXSU.jsandmin/vs/editor-KLE6jdfb.jschunks also contain version 3.4.8.src/main/addon/MonacoEditor.mjs#loadFilesloadsnode_modules/monaco-editor/min/vsdirectly.Consequently, an npm-only override could make dependency scanners green while leaving the browser sanitizer unchanged.
This verifies affected-version presence, not a demonstrated XSS exploit in Neo. These advisories require specific hooks/configuration; no exploitability claim or blanket exemption is made here.
The Architectural Reality
DOMPurify is indirect but not absent from the editor: Monaco uses it for internal HTML/Markdown sanitization. The runtime source comes through VS Code's vendor copy. Upstream already reverted a dependency-only bump for this reason, and Monaco issue 5454 tracks the bundled-copy problem.
Registry verification on 2026-09-05: Monaco latest is 0.56.0, still pinned to 3.4.8. DOMPurify latest is 3.4.14; 3.4.13 meets all four listed advisory floors.
Existing root
overridesinpackage.jsonaddresses gray-matter/js-yaml, but that precedent does not alter already bundled JavaScript. No Engine API or ADR change is needed for a corrected upstream package.The Fix
Current disposition: no corrected upstream distribution; a reproducible consumer-build candidate is now validated below. Keep the alerts visible until the selected production integration repairs both metadata and executed assets.
Upgrade the pinned Monaco package when its shipped editor assets and dependency metadata both contain patched DOMPurify, then regenerate the lockfile and verify the actual editor asset path.
If an earlier local remediation is required, it must be a reproducible Monaco build using patched DOMPurify at module resolution and a verified Neo loader/worker integration. That is a build integration choice, not a package-only override. Do not introduce minified-bundle surgery or an install-time patch as an implicit workaround.
Revalidation trigger: an upstream release/update on microsoft/monaco-editor#5454 or an explicitly selected local rebuild approach.
Contract Ledger Matrix
src/main/addon/MonacoEditor.mjs#loadFilesAcceptance Criteria
Out of Scope
Mermaid updates (its current sanitizer is already patched for these four alerts), replacing Monaco with another editor, unrelated dependency upgrades, and claiming exploitability from version matching alone.
Avoided Traps
Extended investigation — 2026-09-05
The published
latestremains Monaco 0.56.0;nextis 0.56.0-dev-20260625, whose metadata also pins DOMPurify 3.4.8. All four alerts remain open. Mermaid's installed 3.4.13 satisfies these four advisory floors.Exposure in the inspected integration
The four advisories require, respectively: a prior custom Trusted Types policy on the reused instance; persistent
setConfig()plus an allowlist-mutating attribute hook; custom-element handling plus anafterSanitizeElementspolicy; orIN_PLACEplus an element-removal hook. The shipped MonacodomSanitize.jsbuilds per-call configuration, accepts string input, and does not configure those combinations. Its attribute predicate uses per-elementkeepAttr.Executed the current Neo wrapper's AMD editor and JavaScript worker: diagnostics were empty; a custom HTML-capable Markdown hover removed event handlers and
javascript:links, with no marker execution or page error. Separately instrumented the official ESM sanitizer: three exercised calls all used string input, noIN_PLACE, no custom-element configuration, no custom Trusted Types policy, and zerosetConfig/clearConfigcalls. This bounds the observed path; it does not certify every embedder or replace the dependency remediation.Reproducible consumer-build candidate
A working alternative now exists. Using Monaco's official esbuild smoke-build pattern, compiled the published 0.56.0 ESM modules while resolving the vendor import in
domSanitize.jsto the official DOMPurify 3.4.14 ESM distribution. This substitutes a module at build time; no third-party source or minified bundle was edited.domSanitize.js → purify.es.mjsedge, with the old vendor module absent.d02e1a8915eeb1bb4a6d7dd0961e4f4855cbb583d3c9534cc4ad700153c57410.This is an isolated candidate, not the shipped Neo runtime. Production adoption still needs a maintained asset-build entry, Neo loader/worker URL integration, a patched dependency/lock graph, and the existing real-wrapper lifecycle tests against those generated assets. The candidate carries a diagnostic version export that would not be part of the production API. No repository files or alert dispositions changed during these probes.
The complete remediation can therefore proceed through a consumer build if upstream publication remains delayed; the current installed package continues to need repair.
Related
Monaco bundled sanitizer issue, upstream reverted metadata-only bump, DOMPurify 3.4.14 release.
Decision Record impact: none.
Origin Session ID: cb7ccc74-b375-4785-9adf-df6d1112957b
Retrieval Hint:
Monaco 0.56.0 DOMPurify 3.4.8 bundled copy override alert 222 186 164 155Creation freshness: live latest-20 open issue and all-status recent A2A sweeps immediately before filing found no equivalent ticket or competing claim. All-state DOMPurify issue search was empty. Semantic queries returned unrelated older material, so current GitHub, registry metadata, and published package bytes are the evidence.