CVE-2026-63671: @nuxtjs/mdc's URL sanitizer misses SVG xlink:href and data:text/html, allowing XSS from untrusted markdown at the default configuration
@nuxtjs/mdc renders untrusted markdown (including raw HTML) to a Vue component tree. Across two prior advisories it added a URL/attribute sanitizer to block dangerous links in that HTML: validateProps / validateProp and an unsafeLinkPrefix deny-list (dist/runtime/parser/utils/props.js). The sanitizer runs at parse time (dist/runtime/parser/compiler.js) and parseMarkdown enables raw HTML by default (allowDangerousHtml: true, dist/runtime/parser/options.js), so the sanitizer is the only barrier and it applies with no configuration required.
Two sibling vectors bypass that sanitizer at the default configuration:
- SVG anchor
xlink:href.validateProponly scheme-checks attributes named exactlyhreforsrc:
if (attribute === "href" || attribute === "src") return isAnchorLinkAllowed(value);
return true;
An xlink:href (parsed to the hast property xLinkHref) is neither, so a javascript: URL on an SVG <a> is passed through. The renderer maps the property back to the real attribute (MDCRenderer.vue: find(html, "xLinkHref").attribute is xlink:href), so the output element is <a xlink:href="javascript:...">. Clicking it runs the script in the page origin. Plain <a href="javascript:..."> is correctly stripped, which is what makes this the un-patched sibling.
<iframe src="data:text/html,...">.data:text/htmlis present inunsafeLinkPrefix, but the check compares it againsturl.protocol:
if (unsafeLinkPrefix.some((prefix) => url.protocol.toLowerCase().startsWith(prefix))) return false;
For any data URI url.protocol is just "data:", so "data:".startsWith("data:text/html") is always false. Every data:text/* entry in the deny-list is therefore dead code, and <iframe src="data:text/html,<script>...</script>"> is allowed (iframe is not in the render-time dangerousTags, which is only ["script","base"]). The framed document executes script in an opaque origin. For contrast, srcdoc and object are blocked, so this is a precise gap rather than a general absence of filtering.
References
- github.com/advisories/GHSA-mxm6-v9r6-r94c
- github.com/nuxt-content/mdc/commit/61d636c2983f021288e4fc5c4006733b38cf0d53
- github.com/nuxt-content/mdc/pull/491
- github.com/nuxt-content/mdc/releases/tag/v0.22.1
- github.com/nuxt-content/mdc/security/advisories/GHSA-mxm6-v9r6-r94c
- nvd.nist.gov/vuln/detail/CVE-2026-63671
Code Behaviors & Features
Detect and mitigate CVE-2026-63671 with GitLab Dependency Scanning
Secure your software supply chain by verifying that all open source dependencies used in your projects contain no disclosed vulnerabilities. Dependency Scanning using SBOM also detects vulnerabilities from proprietary advisories that this site does not include. Learn more about Dependency Scanning using SBOM →