highCVSS 7.2Vulnerability

GHSA-g2v6-rqmx-r4w6

## Description `@vue/server-renderer` was investigated specifically because it's the one place in Vue where template rendering output becomes a real HTTP response body -- a genuine server-side trust boundary, unlike client-side rendering which only ever affects the same browser session that's already running the app's own JS. `ssrRenderAttrs()` (in `packages/server-renderer/src/helpers/ssrRenderAttrs.ts`) is what compiled SSR output calls for something like `<div v-bind="userObject">`. It loops over the object's own keys and, for each one, renders it as an HTML attribute: ```ts export function ssrRenderDynamicAttr( key: string, value: unknown, tag?: string, ): string { if (!isRenderableAttrValue(value)) { return `` } const attrKey = ... if (isBooleanAttr(attrKey) || ...) { return includeBooleanAttr(value) ? ` ${attrKey}` : `` } else if (isSSRSafeAttrName(attrKey)) { return value === '' ? ` ${attrKey}` : ` ${attrKey}="${escapeHtml(value)}"` } else { console.warn(`[@vue/server-renderer] Skipped rendering unsafe attribute name: ${attrKey}`) return `` } } ``` The value always goes through `escapeHtml()` -- that part is correctly and consistently applied everywhere in this file. But the attribute name (`attrKey`) is only checked against a character blacklist, then spliced directly into the output with no escaping of its own: ```ts // packages/shared/src/domAttrConfig.ts const unsafeAttrCharRE = /[>/="'\u0009\u000a\u000c\u0020]/ export function isSSRSafeAttrName(name: string): boolean { if (attrValidationCache.hasOwnProperty(name)) { return attrValidationCache[name] } const isUnsafe = unsafeAttrCharRE.test(name) if (isUnsafe) { console.error(`unsafe attribute name: ${name}`) } return (attrValidationCache[name] = !isUnsafe) } ``` That blacklist covers: `>`, `/`, `=`, `"`, apostrophe, tab (U+0009), line feed (U+000A), form feed (U+000C), and space (U+0020). It does not cover U+000D -- carriage return (CR, wr

Properties

summary
@vue/server-renderer: XSS via missing CR in attribute-name blacklist
severity
high
cvss_score
7.2
retrieved_at
2026-10-05T22:59:07+00:00
ghsa_published
2026-10-05T22:50:55Z
source_url
https://github.com/advisories/GHSA-g2v6-rqmx-r4w6
ghsa_updated
2026-10-05T22:50:56Z
ghsa_id
GHSA-g2v6-rqmx-r4w6
last_source
GitHub Advisory Database
cve_id
GHSA-g2v6-rqmx-r4w6
cvss_vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N
signal_observed_at
2026-10-05T22:59:07+00:00
is_ghsa_only
true

Related Entities (5)

HAS_WEAKNESS (2)

→[Weakness]Improper Encoding or Escaping of Output
→[Weakness]Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')

REPORTED_BY (1)

→[Source]GitHub Advisory Database

VULNERABLE_TO (1)

←[Software]npm/@vue/server-renderer

AFFECTS (1)

→[Software]npm/@vue/server-renderer

Explore deeper with Ninja Signal's threat intelligence graph

GHSA-g2v6-rqmx-r4w6 (CVSS 7.2) — Ninja Signal Threat Intelligence | Ninja Signal