{"id":"CVE-2026-56317","aliases":["GHSA-m3q2-p4fw-w38m"],"url":"https://o3.security/vulnerability/CVE-2026-56317","summary":"Nuxt - Cross-Site Scripting via NoScript Component Slot Content","details":"### Impact\n\nNuxt's globally registered `<NoScript>` component (from `@unhead/vue` head components, re-exported by Nuxt) wrote its default-slot content to the `innerHTML` of the `<noscript>` head tag, bypassing the HTML escaping that `{{ }}` interpolation normally applies in Vue templates.\n\nApplications that placed untrusted, attacker-controllable data inside a `<NoScript>` slot, for example:\n\n```vue\n<NoScript>{{ route.query.banner }}</NoScript>\n```\n\nwould emit that value unescaped inside `<noscript>` in the server-rendered HTML. With scripting enabled, the HTML parser treats `<noscript>` content in `<head>` under the \"in head noscript\" insertion mode: any tag other than `link`, `meta`, `noframes`, or `style` implicitly closes `<noscript>` and is re-processed in the head. A payload such as `<script>...</script>` therefore escapes the element and executes in the document context.\n\nSibling head components (`<Style>`, `<Title>`) were not affected because they already routed slot text through the safe `textContent` path.\n\n### Affected versions\n\nAll currently supported versions of `nuxt` that ship the `<NoScript>` global component.\n\n### Patches\n\nFixed in `nuxt@4.4.7` (commit [`4b054e9d`](https://github.com/nuxt/nuxt/commit/4b054e9d95f8daf366cb144b52782047c511a66e)) and backported to `nuxt@3.21.7` (commit [`7fea9fd6`](https://github.com/nuxt/nuxt/commit/7fea9fd687f1dacbfb63db5fae5839896b017a0e)). The fix escapes `<NoScript>` slot content with `escapeHtml` from `@vue/shared` and writes it to `textContent` rather than `innerHTML`. Slot content is now rendered as text; intentional markup inside `<NoScript>` is no longer parsed as HTML.\n\n### Workarounds\n\nUntil you can upgrade:\n\n- Do not interpolate untrusted input into `<NoScript>` slots. Replace `<NoScript>{{ x }}</NoScript>` with a static string, or sanitise / HTML-escape `x` at the source.\n- If you must render dynamic noscript content, write the tag yourself via `useHead({ noscript: [{ textContent: escapedValue }] })` after escaping `escapedValue`.\n\n### Credit\n\nReported to Anthropic's coordinated vulnerability disclosure pipeline by Claude (Anthropic's AI assistant) and triaged by the Anthropic security team. Reference: ANT-2026-4NJYDFFM.\n\nIndependently reported by [@alcls01111](https://github.com/alcls01111) via GitHub's coordinated disclosure flow (`GHSA-8grp-wcq9-925q`), closed as a duplicate of this advisory.","published":"2026-06-20T15:21:56.449Z","modified":"2026-10-21T02:30:16.293208765Z","cvss":null,"epss":{"score":0.00342,"percentile":0.2694,"asOf":"2026-09-01"},"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"npm","name":"nuxt","fixedVersion":"4.4.7"},{"ecosystem":"npm","name":"nuxt","fixedVersion":"3.21.7"}],"fix":{"url":"https://github.com/nuxt/nuxt/commit/4b054e9d95f8daf366cb144b52782047c511a66e","label":"nuxt/nuxt@4b054e9"},"references":[{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/56xxx/CVE-2026-56317.json"},{"type":"ADVISORY","url":"https://github.com/nuxt/nuxt/security/advisories/GHSA-m3q2-p4fw-w38m"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-56317"},{"type":"ADVISORY","url":"https://www.vulncheck.com/advisories/nuxt-cross-site-scripting-via-noscript-component-slot-content"},{"type":"FIX","url":"https://github.com/nuxt/nuxt/commit/4b054e9d95f8daf366cb144b52782047c511a66e"},{"type":"FIX","url":"https://github.com/nuxt/nuxt/commit/7fea9fd687f1dacbfb63db5fae5839896b017a0e"},{"type":"PACKAGE","url":"https://github.com/nuxt/nuxt"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-10-21T02:30:16.293208765Z"}}