nuxt-content @nuxtjs/mdc URL sanitizer bypass enables cross-site scripting

Note: This data is for reference and cybersecurity research purposes only.CyStack advises users not to use this information for unlawful purposes.

What is CVE-2026-63671?

CVE-2026-63671 is a vulnerability classified as Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') and Incomplete List of Disallowed Inputs, affecting mdc (affected versions: < 0.22.1). This vulnerability is rated High, with a CVSS score of 8.1. Public exploit code or evidence is available for this vulnerability, but that does not confirm exploitation in the wild.

Overview

Original source data

MDC is a tool to take regular Markdown and write documents interacting deeply with a Vue component. Prior to 0.22.1, @nuxtjs/mdc uses parseMarkdown with allowDangerousHtml enabled by default and relies on validateProps, validateProp, and unsafeLinkPrefix to remove executable URLs from untrusted Markdown. validateProp checks only attributes named href or src, allowing an SVG xlink:href value represented as xLinkHref to retain a javascript: URL that executes in the page origin when selected. The data:text/html denylist entries are also compared against url.protocol, which is only data:, so an iframe src containing data:text/html survives sanitization and executes in an opaque origin when loaded. Plain href javascript: URLs, srcdoc, object, script, and base elements are already blocked, making these two paths specific sibling gaps in the sanitizer. This issue is fixed in version 0.22.1.

Affected products and scope

  • The npm package @nuxtjs/mdc from vendor nuxt-content is affected at versions < 0.22.1.
  • The advisory identifies 0.22.1 as the patched version for the two URL sanitizer gaps.
  • The record does not provide separate status for parallel branches or other release lines beyond the stated boundary; the status of unverified branches should remain unknown.

Technical details

@nuxtjs/mdc converts untrusted Markdown, including raw HTML, into a Vue component tree. parseMarkdown enables allowDangerousHtml by default, making the attribute and URL sanitizer the primary control before content is rendered.

  1. validateProp checks schemes only for attributes named exactly href or src. An SVG xlink:href value is represented as xLinkHref, bypasses that check, and is later mapped by the renderer back to the xlink:href attribute. A javascript: URL can therefore survive and run in the page origin when the user selects the link.
  2. The denylist contains entries such as data:text/html, but the vulnerable code compares them with url.protocol, while the protocol of every data URI is only data:. An iframe with a src containing data:text/html can therefore pass sanitization and execute script when loaded in an opaque origin.

The attacker-controlled input is untrusted Markdown that the application sends to the parser. Ordinary href values containing javascript:, as well as srcdoc, object, script, and base, are already blocked, so this issue consists of two specific sanitizer gaps. The record identifies network reachability and no required privileges, but a deployment must still render content controlled by an attacker for the vulnerable path to apply.

Exploitability

  • Reachability: An attacker must get untrusted Markdown into an application that uses the affected parser. The record describes this path as network-reachable and requiring no privileges.
  • User interaction: The SVG path requires a user to select the xlink:href link. The iframe path executes when the document loads and does not require link selection.
  • Complexity: The record describes low attack complexity once the application renders untrusted content under the default configuration.
  • Public status: The project advisory includes a proof of concept and states that both vectors executed in a current Chromium build. The evidence does not identify a specific campaign or real-world breach.

Technical impact

  • The technical outcome is JavaScript execution through two sanitizer bypasses rather than treating the Markdown only as data.
  • Script from the SVG path runs in the page origin when the link is selected, so it may access or modify resources permitted to that origin; the exact exposure depends on the application and user session.
  • Script in the iframe path runs on load in an opaque origin. This still creates browser-side code execution but is not equivalent to same-origin access from the page origin.
  • The SVG path requires user interaction, while the iframe path can execute on load. The record does not indicate an availability impact or establish a specific real-world compromise.

Business impact

  • Untrusted Markdown can cross the boundary between data and executable code in pages rendered with @nuxtjs/mdc.
  • The SVG path can run script in the page origin after a user selects the link, so practical consequences may include reading or modifying data and interface elements accessible to that page.
  • The iframe path runs script in an opaque origin, creating browser-side execution with different limits from code running in the page origin.
  • Organisational impact depends on the data and actions exposed by the application. The evidence does not establish a specific data disclosure, unauthorized change, or compromise.

Remediation

  1. Upgrade @nuxtjs/mdc to exactly version 0.22.1, which the advisory identifies as patched.
  2. If an upgrade is not currently possible, apply the upstream fix in a tested backport: validate xlinkhref under the same policy as href and src, and compare dangerous prefixes with the full URL so that data:text/html is matched.
  3. Review applications that render untrusted Markdown and restrict that path until the fix is deployed. Disabling raw HTML should be treated as an interim control only after confirming that it removes the affected rendering path.
  4. Recheck stored Markdown and input workflows after updating, especially content containing SVG xlink:href or iframe sources using data:text/html.

Detection

  1. Inventory applications that use @nuxtjs/mdc and determine the deployed version from lockfiles, images, or release artifacts.
  2. Review the Markdown rendering path to determine whether parseMarkdown accepts raw HTML under the default configuration and whether the application renders content supplied by users or external sources.
  3. If the sanitizer is vendored or customized, review validateProps, validateProp, unsafeLinkPrefix, handling for xLinkHref, and whether denylist entries are compared with the full URL rather than only url.protocol.
  4. Review stored Markdown and input sources for SVG anchors using xlink:href and iframe elements whose src begins with data:text/html.
  5. In a test environment, confirm that parsing removes these attributes or sources and does not retain the corresponding xLinkHref or iframe src. No specific IOC or log pattern is established; absence of log evidence does not prove safety.
Sources (12)
Learn more

Run an in-depth assessment with complete web risk management

CyStack VulnScan continuously discovers assets, validates vulnerabilities, and helps security teams prioritize remediation across the organization.