🛡️ CVE-2026-41067 — astro

🟡 CVSS 6.1 — Medium ⚠️ Exploit Public CWE-79 OSV
6.1
CVSS Score
0 Low4 Medium7 High9 Critical10

Description

Astro: XSS in define:vars via incomplete tag sanitization ## Summary The `defineScriptVars` function in Astro's server-side rendering pipeline uses a case-sensitive regex `//g` to sanitize values injected into inline `` tags via the `define:vars` directive. HTML parsers close `` elements case-insensitively and also accept whitespace or `/` before the closing `>`, allowing an attacker to bypass the sanitization with payloads like ``, ``, or `` and inject arbitrary HTML/JavaScript. ## Details The vulnerable function is `defineScriptVars` at `packages/astro/src/runtime/server/render/util.ts:42-53`: ```typescript export function defineScriptVars(vars: Record) { let output = ''; for (const [key, value] of Object.entries(vars)) { output += `const ${toIdent(key)} = ${JSON.stringify(value)?.replace( //g, // ← Case-sensitive, exact match only '\\x3C/script>', )};\n`; } return markHTMLString(output); } ``` This function is called from `renderElement` at `util.ts:172-174` when a `` element has `define:vars`: ```typescript if (name === 'script') { delete props.hoist; children = defineScriptVars(defineVars) + '\n' + children; } ``` The regex `//g` fails to match three classes of closing script tags that HTML parsers accept per the [HTML specification §13.2.6.4](https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inbody): 1. **Case variations**: ``, ``, `` — HTML tag names are case-insensitive but the regex has no `i` flag. 2. **Whitespace before `>`**: ``, ``, `` — after the tag name, the HTML tokenizer enters the "before attribute name" state on ASCII whitespace. 3. **Self-closing slash**: `` — the tokenizer enters "self-closing start tag" state on `/`. `JSON.stringify()` does not escape ``, or `/` characters, so all these payloads pass through serialization unchanged. **Execution flow:** User-controlled input (e.g., `Astro.url.searchParams`) → assigned to a variable → passed via `define:vars` on a `` tag → `renderElement` → `defineScriptVars` → incomplete sanitization → injected into `` block in HTML response → browser closes the script element early → attacker-controlled HTML parsed and executed. ## PoC **Step 1:** Create an SSR Astro page (`src/pages/index.astro`): ```astro const name = Astro.url.searchParams.get('name') || 'World';

Hello

console.log(name); ``` **Step 2:** Ensure SSR is enabled in `astro.config.mjs`: ```js export default defineConfig({ output: 'server' }); ``` **Step 3:** Start the dev server and visit: ``` http://localhost:4321/?name= ``` **Step 4:** View the HTML source. The output contains: ```html const name = ""; console.log(name); ``` The browser's HTML parser matches `` case-insensitively, closing the script block. The `` is then parsed as HTML and the JavaScript in `onerror` executes. **Alternative bypass payloads:** ``` /?name= /?name= /?name= ``` ## Impact An attacker can execute arbitrary JavaScript in the context of a victim's browser session on any SSR Astro application that passes request-derived data to `define:vars` on a `` tag. This is a documented and expected usage pattern in Astro. Exploitation enables: - **Session hijacking** via cookie theft (`document.cookie`) - **Credential theft** by injecting fake login forms or keyloggers - **Defacement** of the rendered page - **Redirection** to attacker-controlled domains The vulnerability affects all Astro versions that support `define:vars` and is exploitable in any SSR deployment where user input reaches a `define:vars` script variable. ## Recommended Fix Replace the case-sensitive exact-match regex with a comprehensive escape that covers all HTML parser edge cases. The simplest correct fix is to escape all `<` characters in the JSON output: ```typescript export function defineScriptVars(vars: Record) { let output = ''; for (const [key, value] of Object.entries(vars)) { output += `const ${toIdent(key)} = ${JSON.stringify(value)?.replace( /</g, '\\u003c', )};\n`; } return markHTMLString(output); } ``` This is the standard approach used by frameworks like Next.js and Rails. Replacing every `<` with `\u003c` is safe inside JSON string contexts (JavaScript treats `\u003c` as `<` at runtime) and eliminates all possible `` variants including case variations, whitespace, and self-closing forms.

How this vulnerability can be exploited

This issue can be reached over the network, attack complexity is low, an attacker needs no privileges on the target. A user must be tricked into taking some action. The scope is changed, meaning a successful attack can affect components beyond the vulnerable one. Rated impact: confidentiality low, integrity low, availability none.

Weakness class

CVE-2026-41067 is classified as CWE-79: Cross-site Scripting (XSS). User-supplied data is written into a page without escaping, so attacker script runs in the browser of anyone who views it.

Affected software

CVE-2026-41067 is recorded against 1 package.

  • astro

Timeline and source

Published on 21 April 2026 and last revised on 17 June 2026. A public exploit is known to exist, which raises the urgency of patching considerably. Record sourced from OSV.

References

github.com (Web)
nvd.nist.gov (Advisory)
github.com (Package)
github.com (Web)

Details

Severity MEDIUM
CVSS Score 6.1
CVSS Vector CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
CWE CWE-79
Public Exploit ⚠️ Yes
Source OSV
Published 2026-04-21
Updated 2026-08-12
Modified 2026-06-17
Fix URL N/A

Affected Packages

Software From version Fixed in
astro

Exploit Protection

Are you running astro?

CVE-2026-41067 carries CVSS 6.1 Medium rating and a public exploit already exists. BotEraser checks your installation against this and other known CVE records, and blocks IPs associated with exploit activity.

Check My Site For CVE-2026-41067 →

No credit card required  ·  Results in minutes

ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.