GHSA-f4j9-crrj-867q: Astro: Reflected XSS via unescaped slot names in @astrojs/svelte

  • Severity: LOW
  • CVE: CVE-2026-126362
  • Ecosystems: npm
  • Packages: @astrojs/svelte

## Summary

The `@astrojs/svelte` renderer wraps slotted content passed to Svelte components in an “ element, and writes the slot name into its `name` attribute without HTML escaping. A slot name containing `”` could end the attribute and inject arbitrary HTML into the page.

For example, a page that takes a slot name from the request:

“`astro
—
import Tabs from ‘../components/Tabs.svelte’;
const tab = Astro.url.searchParams.get(‘tab’);
—
…
“`

rendered with a Svelte 5 component that renders its snippets by name:

“`svelte

{@render snippets[active]?.()}
“`

would output a `tab` value such as `x”>` as live HTML.

## Impact

Reflected cross-site scripting. An attacker who gets a user to open a crafted link can run JavaScript on the site’s origin, but only in applications where all of the following are true:

– The page passes request-controlled input (such as a query parameter) as a slot name.
– The Svelte component is hydrated with a `client:*` directive. For non-hydrated components the slot wrapper is removed from the output, together with its `name` attribute.
– The Svelte component renders the attacker-chosen slot, which in practice means a Svelte 5 component that renders snippets by a dynamic name. Components that never render the slot only output Astro’s already escaped fallback template.

This is the `@astrojs/svelte` counterpart of GHSA-8hv8-536x-4wqp (CVE-2026-50146), which fixed the same issue in `astro` core. The same unescaped value was also used when hyd…

Source: GitHub Security Advisories · 2026-11-12