Parsed HTML anchor links in Markdown provided to parseMarkdown can result in XSS in @nuxtjs/mdc
Date: 2025-02
Affected: npm/@nuxtjs/mdc
Attack vector: xss
Category: vulnerability-disclosure
Severity: Critical
CVE: CVE-2025-24981
CWE: CWE-79
CVSS: 9.3 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:L)

### Summary An unsafe parsing logic of the URL from markdown can lead to arbitrary JavaScript code due to a bypass to the existing guards around the `javascript:` protocol scheme in the URL. ### Details The parsing logic implement at [https://github.com/nuxt-modules/mdc/blob/main/src/runtime/parser/utils/props.ts#L16](https://github.com/nuxt-modules/mdc/blob/main/src/runtime/parser/utils/props.ts#L16) maintains a deny-list approach to filtering potential malicious payload. It does so by matching protocol schemes like `javascript:` and others. Specifically, this is the code from the mdc library's parser that is not secure enough: ```js export const unsafeLinkPrefix = [ 'javascript:', 'data:text/html', 'vbscript:', 'data:text/javascript', 'data:text/vbscript', 'data:text/css', 'data:text/plain', 'data:text/xml' ] export const validateProp = (attribute: string, value: string) => { if (attribute.startsWith('on')) { return false } if (attribute === 'href' || attribute === 'src') { return !unsafeLinkPrefix.some(prefix => value.toLowerCase().startsWith(prefix)) } return true } ``` These security guards can be bypassed by an adversarial that provides JavaScript URLs with HTML entities encoded via hex string. ### PoC The following URL payloads if provided to the markdown parsing library (such as through the usage of `import { parseMarkdown } from '@nuxtjs/mdc/runtime';`) will trigger the alert() dialog: ```markdown # ✅ This is correctly esc


Mitigations:

Architectural layers (MAESTRO):