---
id: "GHSA-jmv2-qgxf-f995"
page: "https://infrastack.ai/live/GHSA-jmv2-qgxf-f995"
kind: "vulnerability"
aliases: ["GHSA-jmv2-qgxf-f995"]
title: "Reflected XSS via unescaped slot names in @astrojs/solid-js"
severity: "medium"
cvss: null
epss: null
exploited: false
status: "open"
category: "package"
products: [{"name": "@astrojs/solid-js", "fixed": ["7.1.2"], "affected": ">= 0.2.0, <= 7.1.1", "ecosystem": "npm"}]
ecosystems: ["npm"]
tags: ["astro", "cwe-79", "npm", "package", "solid-js"]
not_affected_if: ["no-client-directive", "no-dynamic-slot-names", "static-content-only", "version-7.1.2-or-later"]
published_at: "2026-10-28T19:27:28+00:00"
first_seen_at: "2026-11-09T22:53:17+00:00"
updated_at: "2026-11-09T22:58:51+00:00"
sources: [{"source": "ghsa-repo", "url": "https://github.com/withastro/astro/security/advisories/GHSA-jmv2-qgxf-f995", "first_seen_at": "2026-11-09T22:53:17+00:00"}]
exploit_sources: []
---

# Reflected XSS via unescaped slot names in @astrojs/solid-js

Link for people: https://infrastack.ai/live/GHSA-jmv2-qgxf-f995 (this .md is for agents)

The @astrojs/solid-js renderer writes slot names into an HTML attribute without escaping, so a crafted slot name can break out and inject HTML. An attacker who gets a user to open a crafted link can run JavaScript on the site's origin, but only where the page passes request input as a slot name and the Solid component renders that slot by name.

_Summary, check and fix written by a model from the sources; labelled as such._

## Affected

- npm:@astrojs/solid-js affected >= 0.2.0, <= 7.1.1 fixed 7.1.2

## How to check

- Check the installed version with `npm ls @astrojs/solid-js`; versions `>= 0.2.0` and `<= 7.1.1` are affected.
- Look for pages that use request data (such as query parameters) as a slot name in a `client:*` hydrated Solid component.

## Fix

- `@astrojs/solid-js` upgrade to `7.1.2`

## Timeline

- 2026-11-09T22:53:17+00:00 ghsa-repo https://github.com/withastro/astro/security/advisories/GHSA-jmv2-qgxf-f995

## Documents

- [advisory] Maintainer's advisory: github.com https://github.com/withastro/astro/security/advisories/GHSA-jmv2-qgxf-f995

## From the sources

## Summary

The `@astrojs/solid-js` renderer wraps named slot content passed to Solid components in an `<astro-slot>` 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.jsx';
const tab = Astro.url.searchParams.get('tab');
---
<Tabs client:load active={tab}><div slot={tab}>…</div></Tabs>
```

rendered with a Solid component that renders a slot by name:

```jsx
export default function Tabs(props) {
	return <div>{props[props.active]}</div>;
}
```

would output a `tab` value such as `x"><img src=x onerror=alert(1)>` 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 Solid 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 Solid component renders the attacker-chosen slot, which in practice means accessing slot props by a dynamic name. Components that never render the slot only output Astro's already escaped fallback template.

This is the `@astrojs/solid-js` counterpart of GHSA-8hv8-536x-4wqp (CVE-2026-50146), which fixed the same issue in `astro` core.

## Affected versions

`@astrojs/solid-js` >= 0.2.0, <= 7.1.1.

## Patches

Fixed in `@astrojs/solid-js` 7.1.2. Slot names are now HTML-escaped in the server renderer.

## Workarounds

Upgrade to `@astrojs/solid-js` 7.1.2 or later. Before upgrading, do not use request-controlled input as a slot name, or map it to a fixed set of known slot names before passing it to a component.

## Credits

Reported by @manus-pi.

---

_Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai_
