You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This issue concerns Astro's remotePatterns path enforcement for remote URLs used by server-side fetchers such as the image optimization endpoint. The path matching logic for /* wildcards is unanchored, so a pathname that contains the allowed prefix later in the path can still match. As a result, an attacker can fetch paths outside the intended allowlisted prefix on an otherwise allowed host. In our PoC, both the allowed path and a bypass path returned 200 with the same SVG payload, confirming the bypass.
Impact
Attackers can fetch unintended remote resources on an allowlisted host via the image endpoint, expanding SSRF/data exposure beyond the configured path prefix.
isRemoteAllowed() evaluates remotePatterns for a requested URL.
matchPathname() handles pathname: "/img/*" using .replace() on the URL path.
A path such as /evil/img/secret incorrectly matches because /img/ is removed even when it's not at the start.
The image endpoint fetches and returns the remote resource.
PoC
The PoC starts a local attacker server and configures remotePatterns to allow only /img/*. It then requests the image endpoint with two URLs: an allowed path and a bypass path with /img/ in the middle. Both requests returned the SVG payload, showing the path restriction was bypassed.
The defineScriptVars function in Astro's server-side rendering pipeline uses a case-sensitive regex /<\/script>/g to sanitize values injected into inline <script> tags via the define:vars directive. HTML parsers close <script> elements case-insensitively and also accept whitespace or / before the closing >, allowing an attacker to bypass the sanitization with payloads like </Script>, </script >, or </script/> and inject arbitrary HTML/JavaScript.
Details
The vulnerable function is defineScriptVars at packages/astro/src/runtime/server/render/util.ts:42-53:
exportfunctiondefineScriptVars(vars: Record<any,any>){letoutput='';for(const[key,value]ofObject.entries(vars)){output+=`const ${toIdent(key)} = ${JSON.stringify(value)?.replace(/<\/script>/g,// ← Case-sensitive, exact match only'\\x3C/script>',)};\n`;}returnmarkHTMLString(output);}
This function is called from renderElement at util.ts:172-174 when a <script> element has define:vars:
The regex /<\/script>/g fails to match three classes of closing script tags that HTML parsers accept per the HTML specification §13.2.6.4:
Case variations: </Script>, </SCRIPT>, </sCrIpT> — HTML tag names are case-insensitive but the regex has no i flag.
Whitespace before >: </script >, </script\t>, </script\n> — after the tag name, the HTML tokenizer enters the "before attribute name" state on ASCII whitespace.
Self-closing slash: </script/> — 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 <script> tag → renderElement → defineScriptVars → incomplete sanitization → injected into <script> 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):
The browser's HTML parser matches </Script> case-insensitively, closing the script block. The <img onerror=alert(document.cookie)> is then parsed as HTML and the JavaScript in onerror executes.
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 <script> 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:
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 </script> variants including case variations, whitespace, and self-closing forms.
#16202b5c2fba Thanks @matthewp! - Fixes Actions failing with ActionsWithoutServerOutputError when using output: 'static' with an adapter
#16303b06eabf Thanks @matthewp! - Improves handling of special characters in inline <script> content
#14924bb4586a Thanks @aralroca! - Fixes SCSS and CSS module file changes triggering a full page reload instead of hot-updating styles in place during development
#161715bcd03c Thanks @Desel72! - Fixes a build error that occurred when a pre-rendered page used the <Picture> component and another page called render() on content collection entries.
#162397c65c04 Thanks @dataCenter430! - Fixes sync content inside <Fragment> not streaming to the browser until all async sibling expressions have resolved.
#16242686c312 Thanks @martrapp! - Revives UnoCSS in dev mode when used with the client router.
This change partly reverts #16089, which in hindsight turned out to be too general. Instead of automatically persisting all style sheets, we now do this only for styles from Vue components.
When creating new projects, astro add cloudflare now sets compatibility_date to the current date. Previously, this date was resolved from locally installed packages, which could be unreliable in some package manager environments. Using today’s date is simpler and more reliable across environments, and is supported by workerd.
#1619721f9fe2 Thanks @SchahinRohani! - Remove unused re-exports from assets/utils barrel file to fix Vite build warning
#160596d5469e Thanks @matthewp! - Fixes Expected 'miniflare' to be defined errors and 404 responses in dev mode when using the Cloudflare adapter and the config file changes. Instead of creating a brand new Vite server on config changes, Astro now performs a Vite in-place restart, allowing the Cloudflare adapter to reuse its existing miniflare instance across restarts.
#161547610ba4 Thanks @Desel72! - Fixes pages with dots in their filenames (e.g. hello.world.astro) returning 404 when accessed with a trailing slash in the dev server. The trailingSlashForPath function now only forces trailingSlash: 'never' for endpoints with file extensions, allowing pages to correctly respect the user's trailingSlash config.
#1619323425e2 Thanks @matthewp! - Fixes trailingSlash: "always" producing redirect HTML instead of the actual response for extensionless endpoints during static builds
#16161b51f297 Thanks @matthewp! - Fixes a dev rendering issue with the Cloudflare adapter where head metadata could be missing and dev CSS/scripts could be injected in the wrong place
#16110de669f0 Thanks @tmimmanuel! - Fixes skew protection query parameters not being appended to inter-chunk JavaScript imports in client bundles, which could cause version mismatches during rolling deployments on Vercel
#16162a0a49e9 Thanks @rururux! - Fixes an issue where HMR would not trigger when modifying files while using @astrojs/cloudflare with prerenderEnvironment: 'node' enabled.
#161427454854 Thanks @rururux! - Fixes HTML content being incorrectly escaped as plain text when rendering a MDX component using the AstroContainer APIs.
#1611612602a9 Thanks @riderx! - Fixes a bug where page-level CSS could leak between unrelated pages when traversing style parents across top-level route boundaries
#16178a7e7567 Thanks @matthewp! - Fixes SSR builds failing with "No matching renderer found" when a project only has injected routes and no src/pages/ directory
#1610447a394d Thanks @matthewp! - Fixes astro preview ignoring vite.preview.allowedHosts set in astro.config.mjs
#16047711f837 Thanks @matthewp! - Fixes catch-all routes incorrectly intercepting requests for static assets when using the @astrojs/node adapter in middleware mode.
#15981a60cbb6 Thanks @moktamd! - Fix Zod v4 validation error formatting to show human-readable messages instead of raw JSON
#15804a5e7232 Thanks @merlinnot! - Allows setting codec-specific defaults for Astro's built-in Sharp image service via image.service.config.
You can now configure encoder-level options such as jpeg.mozjpeg, webp.effort, webp.alphaQuality, avif.effort, avif.chromaSubsampling, and png.compressionLevel when using astro/assets/services/sharp for compile-time image generation.
These settings apply as defaults for the built-in Sharp pipeline, while per-image quality still takes precedence when set on <Image />, <Picture />, or getImage().
#15455babf57f Thanks @AhmadYasser1! - Adds fallbackRoutes to the IntegrationResolvedRoute type, exposing i18n fallback routes to integrations via the astro:routes:resolved hook for projects using fallbackType: 'rewrite'.
This allows integrations such as the sitemap integration to properly include generated fallback routes in their output.
{'astro:routes:resolved': ({ routes })=>{for(constrouteofroutes){for(constfallbackofroute.fallbackRoutes){console.log(fallback.pathname)// e.g. /fr/about/}}}}
You can now pass an options object to markdown.smartypants in your Astro configuration to fine-tune how punctuation, dashes, and quotes are transformed.
This is helpful for projects that require specific typographic standards, such as "oldschool" dash handling or localized quotation marks.
#16025a09f319 Thanks @koji-1009! - Instructs the client router to skip view transition animations when the browser is already providing its own visual transition, such as a swipe gesture.
#16055ccecb8f Thanks @Gautam-Bharadwaj! - Fixes an issue where client:only components could have duplicate client:component-path attributes added in MDX in rare cases
#1608144fc340 Thanks @crazylogic03! - Fixes the emitFile() is not supported in serve mode warning that appears during astro dev when using integrations that inject before-hydration scripts (e.g. @astrojs/react)
#1606831d733b Thanks @Karthikeya1500! - Fixes the dev toolbar a11y audit incorrectly classifying menuitemradio as a non-interactive ARIA role.
#16080e80ac73 Thanks @ematipico! - Fixes experimental.queuedRendering incorrectly escaping the HTML output of .html page files, causing the page content to render as plain text instead of HTML in the browser.
#1604813b9d56 Thanks @matthewp! - Fixes a dev server crash (serverIslandNameMap.get is not a function) that occurred when navigating to a page with server:defer after first visiting a page without one, when using @astrojs/cloudflare
#16093336e086 Thanks @Snugug! - Fixes Zod meta not correctly being rendered on top-level schema when converted into JSON Schema
#16043d402485 Thanks @ematipico! - Fixes checkOrigin CSRF protection in astro dev behind a TLS-terminating reverse proxy. The dev server now reads X-Forwarded-Proto (gated on security.allowedDomains, matching production behaviour) so the constructed request origin matches the https:// origin the browser sends. Also ensures security.allowedDomains and security.checkOrigin are respected in dev.
#16064ba58e0d Thanks @ematipico! - Updates the dependency svgo to the latest, to fix a security issue.
#160072dcd8d5 Thanks @florian-lefebvre! - Fixes a case where fonts files would unecessarily be copied several times during the build
#16017b089b90 Thanks @felmonon! - Fix the astro sync error message when getImage() is called while loading content collections.
#16014fa73fbb Thanks @matthewp! - Fixes a build error where using astro:config/client inside a <script> tag would cause Rollup to fail with "failed to resolve import virtual:astro:routes from virtual:astro:manifest"
#16054f74465a Thanks @seroperson! - Fixes an issue with the development server, where changes to the middleware weren't picked, and it required a full restart of the server.
#16033198d31b Thanks @adampage! - Fixes a bug where the the role image was incorrectly reported by audit tool bar.
#15935278828c Thanks @oliverlynch! - Fixes cached assets failing to revalidate due to redirect check mishandling Not Modified responses.
#160752c1ae85 Thanks @florian-lefebvre! - Fixes a case where invalid URLs would be generated in development when using font families with an oblique style and angles
#1606287fd6a4 Thanks @matthewp! - Warns on dev server startup when Vite 8 is detected at the top level of the user's project, and automatically adds a "overrides": { "vite": "^7" } entry to package.json when running astro add cloudflare. This prevents a require_dist is not a function crash caused by a Vite version split between Astro (requires Vite 7) and packages like @tailwindcss/vite that hoist Vite 8.
#159786d182fe Thanks @seroperson! - Fixes a bug where Astro Actions didn't properly support nested object properties, causing problems when users used zod functions such as superRefine or discriminatedUnion.
#16011e752170 Thanks @matthewp! - Fixes a dev server hang on the first request when using the Cloudflare adapter
#159971fddff7 Thanks @ematipico! - Fixes Astro.rewrite() failing when the target path contains duplicate slashes (e.g. //about). The duplicate slashes are now collapsed before URL parsing, preventing them from being interpreted as a protocol-relative URL.
#15950acce5e8 Thanks @matthewp! - Fixes a build regression in projects with multiple frontend integrations where server:defer server islands could fail at runtime when all pages are prerendered.
#15988c93b4a0 Thanks @ossaidqadri! - Fix styles from dynamically imported components not being injected on first dev server load.
#159683e7a9d5 Thanks @chasemccoy! - Fixes renderMarkdown in custom content loaders not resolving images in markdown content. Images referenced in markdown processed by renderMarkdown are now correctly optimized, matching the behavior of the built-in glob() loader.
#159901e6017f Thanks @ematipico! - Fixes an issue where Astro.currentLocale would always be the default locale instead of the actual one when using a dynamic route like [locale].astro or [locale]/index.astro. It now resolves to the correct locale from the URL.
#159901e6017f Thanks @ematipico! - Fixes an issue where visiting an invalid locale URL (e.g. /asdf/) would show the content of a dynamic [locale] page with a 404 status code, instead of showing your custom 404 page. Now, the correct 404 page is rendered when the locale in the URL doesn't match any configured locale.
#159601d84020 Thanks @matthewp! - Fixes Cloudflare dev server islands with prerenderEnvironment: 'node' by sharing the serialized manifest encryption key across dev environments and routing server island requests through the SSR runtime.
#157359685e2d Thanks @fa-sharp! - Fixes an EventEmitter memory leak when serving static pages from Node.js middleware.
When using the middleware handler, requests that were being passed on to Express / Fastify (e.g. static files / pre-rendered pages / etc.) weren't cleaning up socket listeners before calling next(), causing a memory leak warning. This fix makes sure to run the cleanup before calling next().
#159652dca307 Thanks @matthewp! - Fixes client hydration for components imported through Node.js subpath imports (package.json#imports, e.g. #components/*), for example when using the Cloudflare adapter in development.
#157706102ca2 Thanks @jpc-ae! - Updates the create astro welcome message to highlight the graceful dev/preview server quit command rather than the kill process shortcut
#159537eddf22 Thanks @Desel72! - fix(hmr): eagerly recompile on style-only change to prevent stale slots render
#159165201ed4 Thanks @trueberryless! - Fixes InferLoaderSchema type inference for content collections defined with a loader that includes a schema
#15864d3c7de9 Thanks @florian-lefebvre! - Removes temporary support for Node >=20.19.1 because Stackblitz now uses Node 22 by default
#15944a5e1acd Thanks @fkatsuhiro! - Fixes SSR dynamic routes with .html extension (e.g. [slug].html.astro) not working
#15937d236245 Thanks @ematipico! - Fixes an issue where HMR didn't correctly work on Windows when adding/changing/deleting routes in pages/.
#1593198dfb61 Thanks @Strernd! - Fix skew protection query params not being applied to island hydration component-url and renderer-url, and ensure query params are appended safely for asset URLs with existing search/hash parts.
#15891b889231 Thanks @matthewp! - Fix dev routing for server:defer islands when adapters opt into handling prerendered routes in Astro core. Server island requests are now treated as prerender-handler eligible so prerendered pages using prerenderEnvironment: 'node' can load island content without 400 errors.
#15890765a887 Thanks @matthewp! - Fixes astro:actions validation to check resolved routes, so projects using default static output with at least one prerender = false page or endpoint no longer fail during startup.
#15884dcd2c8e Thanks @matthewp! - Avoid a MaxListenersExceededWarning during astro dev startup by increasing the shared Vite watcher listener limit when attaching content server listeners.
#1590423d5244 Thanks @jlukic! - Emit the before-hydration script chunk for the client Vite environment. The chunk was only emitted for prerender and ssr environments, causing a 404 when browsers tried to load it. This broke hydration for any integration using injectScript('before-hydration', ...), including Lit SSR.
#15933325901e Thanks @ematipico! - Fixes an issue where <style> tags inside SVG components weren't correctly tracked when enabling CSP.
#15875c43ef8a Thanks @matthewp! - Ensure custom prerenderers are always torn down during build, even when getStaticPaths() throws.
#158871861fed Thanks @ematipico! - Fixes an issue where the build incorrectly leaked server entrypoint into the client environment, causing adapters to emit warnings during the build.
#15888925252e Thanks @matthewp! - Fix a bug where server:defer could fail at runtime in prerendered pages for some adapters (including Cloudflare), causing errors like serverIslandMap?.get is not a function.
#1590107c1002 Thanks @delucis! - Fixes JSON schema generation for content collection schemas that have differences between their input and output shapes.
#15882759f946 Thanks @matthewp! - Fix Astro.url.pathname for the root page when using build.format: "file" so it resolves to /index.html instead of /.html during builds.
#15870920f10b Thanks @matthewp! - Prebundle astro/toolbar in dev when custom dev toolbar apps are registered, preventing re-optimization reloads that can hide or break the toolbar.
#15876f47ac53 Thanks @ematipico! - Fixes redirectToDefaultLocale producing a protocol-relative URL (//locale) instead of an absolute path (/locale) when base is '/'.
#15767e0042f7 Thanks @matthewp! - Fixes server islands (server:defer) not working when only used in prerendered pages with output: 'server'.
#1587335841ed Thanks @matthewp! - Fix a dev server bug where newly created pages could miss layout-imported CSS until restart.
#1575458f1d63 Thanks @rururux! - Fixes a bug where a directory at the project root sharing the same name as a page route would cause the dev server to return a 404 instead of serving the page.
#1586976b3a5e Thanks @matthewp! - Update the unknown file extension error hint to recommend vite.resolve.noExternal, which is the correct Vite 7 config key.
#15711b2bd27b Thanks @OliverSpeir! - Improves Astro core's dev environment handling for prerendered routes by ensuring route/CSS updates and prerender middleware behavior work correctly across both SSR and prerender environments.
This enables integrations that use Astro's prerender dev environment (such as Cloudflare with prerenderEnvironment: 'node') to get consistent route matching and HMR behavior during development.
#158521cdaf9f Thanks @ematipico! - Fixes a regression where the the routes emitted by the astro:build:done hook didn't have the distURL array correctly populated.
#15765ca76ff1 Thanks @matthewp! - Hardens server island POST endpoint validation to use own-property checks for improved consistency
#154619f21b24 Thanks @florian-lefebvre! - BREAKING CHANGE to the v6 beta Adapter API only: renames entryType to entrypointResolution and updates possible values
Astro 6 introduced a way to let adapters have more control over the entrypoint by passing entryType: 'self' to setAdapter(). However during beta development, the name was unclear and confusing.
entryType is now renamed to entrypointResolution and its possible values are updated:
legacy-dynamic becomes explicit.
self becomes auto.
If you are building an adapter with v6 beta and specifying entryType, update it:
Next steps: Take a moment to review the security alert above. Review
the linked package source code to understand the potential risk. Ensure the
package is not malicious before proceeding. If you're unsure how to proceed,
reach out to your security team or ask the Socket team for help at
support@socket.dev.
Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.
Mark the package as acceptable risk. To ignore this alert only
in this pull request, reply with the comment
@SocketSecurity ignore npm/astro@6.3.1. You can
also ignore all packages with @SocketSecurity ignore-all.
To ignore an alert for all future pull requests, use Socket's Dashboard to
change the triage state of this alert.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
^5.13.2→^6.0.0Astro: Remote allowlist bypass via unanchored matchPathname wildcard
CVE-2026-33769 / GHSA-g735-7g2w-hh3f
More information
Details
Summary
This issue concerns Astro's
remotePatternspath enforcement for remote URLs used by server-side fetchers such as the image optimization endpoint. The path matching logic for/*wildcards is unanchored, so a pathname that contains the allowed prefix later in the path can still match. As a result, an attacker can fetch paths outside the intended allowlisted prefix on an otherwise allowed host. In our PoC, both the allowed path and a bypass path returned 200 with the same SVG payload, confirming the bypass.Impact
Attackers can fetch unintended remote resources on an allowlisted host via the image endpoint, expanding SSRF/data exposure beyond the configured path prefix.
Description
Taint flow: request ->
transform.src->isRemoteAllowed()->matchPattern()->matchPathname()User-controlled
hrefis parsed intotransform.srcand validated viaisRemoteAllowed():Source: https://github.com/withastro/astro/blob/e0f1a2b3e4bc908bd5e148c698efb6f41a42c8ea/packages/astro/src/assets/endpoint/generic.ts#L43-L56
isRemoteAllowed()checks eachremotePatternviamatchPattern():Source: https://github.com/withastro/astro/blob/e0f1a2b3e4bc908bd5e148c698efb6f41a42c8ea/packages/internal-helpers/src/remote.ts#L15-L21
The vulnerable logic in
matchPathname()usesreplace()without anchoring the prefix for/*patterns:Source: https://github.com/withastro/astro/blob/e0f1a2b3e4bc908bd5e148c698efb6f41a42c8ea/packages/internal-helpers/src/remote.ts#L85-L99
Vulnerable code flow:
isRemoteAllowed()evaluatesremotePatternsfor a requested URL.matchPathname()handlespathname: "/img/*"using.replace()on the URL path./evil/img/secretincorrectly matches because/img/is removed even when it's not at the start.PoC
The PoC starts a local attacker server and configures remotePatterns to allow only
/img/*. It then requests the image endpoint with two URLs: an allowed path and a bypass path with/img/in the middle. Both requests returned the SVG payload, showing the path restriction was bypassed.Vulnerable config
Affected pages
This PoC targets the
/_imageendpoint directly; no additional pages are required.PoC Code
Attacker server
PoC Steps
Severity
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N/E:PReferences
This data is provided by OSV and the GitHub Advisory Database (CC-BY 4.0).
Astro: XSS in define:vars via incomplete </script> tag sanitization
CVE-2026-41067 / GHSA-j687-52p2-xcff
More information
Details
Summary
The
defineScriptVarsfunction in Astro's server-side rendering pipeline uses a case-sensitive regex/<\/script>/gto sanitize values injected into inline<script>tags via thedefine:varsdirective. HTML parsers close<script>elements case-insensitively and also accept whitespace or/before the closing>, allowing an attacker to bypass the sanitization with payloads like</Script>,</script >, or</script/>and inject arbitrary HTML/JavaScript.Details
The vulnerable function is
defineScriptVarsatpackages/astro/src/runtime/server/render/util.ts:42-53:This function is called from
renderElementatutil.ts:172-174when a<script>element hasdefine:vars:The regex
/<\/script>/gfails to match three classes of closing script tags that HTML parsers accept per the HTML specification §13.2.6.4:</Script>,</SCRIPT>,</sCrIpT>— HTML tag names are case-insensitive but the regex has noiflag.>:</script >,</script\t>,</script\n>— after the tag name, the HTML tokenizer enters the "before attribute name" state on ASCII whitespace.</script/>— 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 viadefine:varson a<script>tag →renderElement→defineScriptVars→ incomplete sanitization → injected into<script>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):Step 2: Ensure SSR is enabled in
astro.config.mjs:Step 3: Start the dev server and visit:
Step 4: View the HTML source. The output contains:
The browser's HTML parser matches
</Script>case-insensitively, closing the script block. The<img onerror=alert(document.cookie)>is then parsed as HTML and the JavaScript inonerrorexecutes.Alternative bypass payloads:
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:varson a<script>tag. This is a documented and expected usage pattern in Astro.Exploitation enables:
document.cookie)The vulnerability affects all Astro versions that support
define:varsand is exploitable in any SSR deployment where user input reaches adefine:varsscript 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:This is the standard approach used by frameworks like Next.js and Rails. Replacing every
<with\u003cis safe inside JSON string contexts (JavaScript treats\u003cas<at runtime) and eliminates all possible</script>variants including case variations, whitespace, and self-closing forms.Severity
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:NReferences
This data is provided by OSV and the GitHub Advisory Database (CC-BY 4.0).
Release Notes
withastro/astro (astro)
v6.1.6Compare Source
Patch Changes
#16202
b5c2fbaThanks @matthewp! - Fixes Actions failing withActionsWithoutServerOutputErrorwhen usingoutput: 'static'with an adapter#16303
b06eabfThanks @matthewp! - Improves handling of special characters in inline<script>content#14924
bb4586aThanks @aralroca! - Fixes SCSS and CSS module file changes triggering a full page reload instead of hot-updating styles in place during developmentv6.1.5Compare Source
Patch Changes
#16171
5bcd03cThanks @Desel72! - Fixes a build error that occurred when a pre-rendered page used the<Picture>component and another page calledrender()on content collection entries.#16239
7c65c04Thanks @dataCenter430! - Fixes sync content inside<Fragment>not streaming to the browser until all async sibling expressions have resolved.#16242
686c312Thanks @martrapp! - Revives UnoCSS in dev mode when used with the client router.This change partly reverts #16089, which in hindsight turned out to be too general. Instead of automatically persisting all style sheets, we now do this only for styles from Vue components.
#16192
79d86b8Thanks @alexanderniebuhr! - Uses today’s date for Cloudflarecompatibility_dateinastro add cloudflareWhen creating new projects,
astro add cloudflarenow setscompatibility_dateto the current date. Previously, this date was resolved from locally installed packages, which could be unreliable in some package manager environments. Using today’s date is simpler and more reliable across environments, and is supported byworkerd.#16259
34df955Thanks @gameroman! - Removeddlvdependencyv6.1.4Compare Source
Patch Changes
#16197
21f9fe2Thanks @SchahinRohani! - Remove unused re-exports from assets/utils barrel file to fix Vite build warning#16059
6d5469eThanks @matthewp! - FixesExpected 'miniflare' to be definederrors and 404 responses in dev mode when using the Cloudflare adapter and the config file changes. Instead of creating a brand new Vite server on config changes, Astro now performs a Vite in-place restart, allowing the Cloudflare adapter to reuse its existing miniflare instance across restarts.#16154
7610ba4Thanks @Desel72! - Fixes pages with dots in their filenames (e.g.hello.world.astro) returning 404 when accessed with a trailing slash in the dev server. ThetrailingSlashForPathfunction now only forcestrailingSlash: 'never'for endpoints with file extensions, allowing pages to correctly respect the user'strailingSlashconfig.#16193
23425e2Thanks @matthewp! - FixestrailingSlash: "always"producing redirect HTML instead of the actual response for extensionless endpoints during static buildsv6.1.3Compare Source
Patch Changes
#16161
b51f297Thanks @matthewp! - Fixes a dev rendering issue with the Cloudflare adapter where head metadata could be missing and dev CSS/scripts could be injected in the wrong place#16110
de669f0Thanks @tmimmanuel! - Fixes skew protection query parameters not being appended to inter-chunk JavaScript imports in client bundles, which could cause version mismatches during rolling deployments on Vercel#16162
a0a49e9Thanks @rururux! - Fixes an issue where HMR would not trigger when modifying files while using @astrojs/cloudflare with prerenderEnvironment: 'node' enabled.#16142
7454854Thanks @rururux! - Fixes HTML content being incorrectly escaped as plain text when rendering a MDX component using theAstroContainerAPIs.#16116
12602a9Thanks @riderx! - Fixes a bug where page-level CSS could leak between unrelated pages when traversing style parents across top-level route boundaries#16178
a7e7567Thanks @matthewp! - Fixes SSR builds failing with "No matching renderer found" when a project only has injected routes and nosrc/pages/directoryv6.1.2Compare Source
Patch Changes
#16104
47a394dThanks @matthewp! - Fixesastro previewignoringvite.preview.allowedHostsset inastro.config.mjs#16047
711f837Thanks @matthewp! - Fixes catch-all routes incorrectly intercepting requests for static assets when using the@astrojs/nodeadapter in middleware mode.#15981
a60cbb6Thanks @moktamd! - Fix Zod v4 validation error formatting to show human-readable messages instead of raw JSONv6.1.1Compare Source
Patch Changes
#16105
23d60deThanks @matthewp! - Fix dev toolbar audit crash when encountering theimageARIA role#16089
999c875Thanks @martrapp! - Fixes an issue with the client router where Vue's:deep()notation was ignored in dev mode.v6.1.0Compare Source
Minor Changes
#15804
a5e7232Thanks @merlinnot! - Allows setting codec-specific defaults for Astro's built-in Sharp image service viaimage.service.config.You can now configure encoder-level options such as
jpeg.mozjpeg,webp.effort,webp.alphaQuality,avif.effort,avif.chromaSubsampling, andpng.compressionLevelwhen usingastro/assets/services/sharpfor compile-time image generation.These settings apply as defaults for the built-in Sharp pipeline, while per-image
qualitystill takes precedence when set on<Image />,<Picture />, orgetImage().#15455
babf57fThanks @AhmadYasser1! - AddsfallbackRoutesto theIntegrationResolvedRoutetype, exposing i18n fallback routes to integrations via theastro:routes:resolvedhook for projects usingfallbackType: 'rewrite'.This allows integrations such as the sitemap integration to properly include generated fallback routes in their output.
#15340
10a1a5aThanks @trueberryless! - Adds support for advanced configuration of SmartyPants in Markdown.You can now pass an options object to
markdown.smartypantsin your Astro configuration to fine-tune how punctuation, dashes, and quotes are transformed.This is helpful for projects that require specific typographic standards, such as "oldschool" dash handling or localized quotation marks.
See the
retext-smartypantsoptions for more information.Patch Changes
#16025
a09f319Thanks @koji-1009! - Instructs the client router to skip view transition animations when the browser is already providing its own visual transition, such as a swipe gesture.#16055
ccecb8fThanks @Gautam-Bharadwaj! - Fixes an issue whereclient:onlycomponents could have duplicateclient:component-pathattributes added in MDX in rare cases#16081
44fc340Thanks @crazylogic03! - Fixes theemitFile() is not supported in serve modewarning that appears duringastro devwhen using integrations that inject before-hydration scripts (e.g.@astrojs/react)#16068
31d733bThanks @Karthikeya1500! - Fixes the dev toolbar a11y audit incorrectly classifyingmenuitemradioas a non-interactive ARIA role.#16080
e80ac73Thanks @ematipico! - Fixesexperimental.queuedRenderingincorrectly escaping the HTML output of.htmlpage files, causing the page content to render as plain text instead of HTML in the browser.#16048
13b9d56Thanks @matthewp! - Fixes a dev server crash (serverIslandNameMap.get is not a function) that occurred when navigating to a page withserver:deferafter first visiting a page without one, when using@astrojs/cloudflare#16093
336e086Thanks @Snugug! - Fixes Zod meta not correctly being rendered on top-level schema when converted into JSON Schema#16043
d402485Thanks @ematipico! - FixescheckOriginCSRF protection inastro devbehind a TLS-terminating reverse proxy. The dev server now readsX-Forwarded-Proto(gated onsecurity.allowedDomains, matching production behaviour) so the constructed request origin matches thehttps://origin the browser sends. Also ensuressecurity.allowedDomainsandsecurity.checkOriginare respected in dev.#16064
ba58e0dThanks @ematipico! - Updates the dependencysvgoto the latest, to fix a security issue.#16007
2dcd8d5Thanks @florian-lefebvre! - Fixes a case where fonts files would unecessarily be copied several times during the build#16017
b089b90Thanks @felmonon! - Fix theastro syncerror message whengetImage()is called while loading content collections.#16014
fa73fbbThanks @matthewp! - Fixes a build error where usingastro:config/clientinside a<script>tag would cause Rollup to fail with "failed to resolve importvirtual:astro:routesfromvirtual:astro:manifest"#16054
f74465aThanks @seroperson! - Fixes an issue with the development server, where changes to the middleware weren't picked, and it required a full restart of the server.#16033
198d31bThanks @adampage! - Fixes a bug where the the roleimagewas incorrectly reported by audit tool bar.#15935
278828cThanks @oliverlynch! - Fixes cached assets failing to revalidate due to redirect check mishandling Not Modified responses.#16075
2c1ae85Thanks @florian-lefebvre! - Fixes a case where invalid URLs would be generated in development when using font families with an obliquestyleand angles#16062
87fd6a4Thanks @matthewp! - Warns on dev server startup when Vite 8 is detected at the top level of the user's project, and automatically adds a"overrides": { "vite": "^7" }entry topackage.jsonwhen runningastro add cloudflare. This prevents arequire_dist is not a functioncrash caused by a Vite version split between Astro (requires Vite 7) and packages like@tailwindcss/vitethat hoist Vite 8.Updated dependencies [
10a1a5a]:v6.0.8Compare Source
Patch Changes
#15978
6d182feThanks @seroperson! - Fixes a bug where Astro Actions didn't properly support nested object properties, causing problems when users used zod functions such assuperRefineordiscriminatedUnion.#16011
e752170Thanks @matthewp! - Fixes a dev server hang on the first request when using the Cloudflare adapter#15997
1fddff7Thanks @ematipico! - FixesAstro.rewrite()failing when the target path contains duplicate slashes (e.g.//about). The duplicate slashes are now collapsed before URL parsing, preventing them from being interpreted as a protocol-relative URL.v6.0.7Compare Source
Patch Changes
#15950
acce5e8Thanks @matthewp! - Fixes a build regression in projects with multiple frontend integrations whereserver:deferserver islands could fail at runtime when all pages are prerendered.#15988
c93b4a0Thanks @ossaidqadri! - Fix styles from dynamically imported components not being injected on first dev server load.#15968
3e7a9d5Thanks @chasemccoy! - FixesrenderMarkdownin custom content loaders not resolving images in markdown content. Images referenced in markdown processed byrenderMarkdownare now correctly optimized, matching the behavior of the built-inglob()loader.#15990
1e6017fThanks @ematipico! - Fixes an issue whereAstro.currentLocalewould always be the default locale instead of the actual one when using a dynamic route like[locale].astroor[locale]/index.astro. It now resolves to the correct locale from the URL.#15990
1e6017fThanks @ematipico! - Fixes an issue where visiting an invalid locale URL (e.g./asdf/) would show the content of a dynamic[locale]page with a 404 status code, instead of showing your custom 404 page. Now, the correct 404 page is rendered when the locale in the URL doesn't match any configured locale.#15960
1d84020Thanks @matthewp! - Fixes Cloudflare dev server islands withprerenderEnvironment: 'node'by sharing the serialized manifest encryption key across dev environments and routing server island requests through the SSR runtime.#15735
9685e2dThanks @fa-sharp! - Fixes an EventEmitter memory leak when serving static pages from Node.js middleware.When using the middleware handler, requests that were being passed on to Express / Fastify (e.g. static files / pre-rendered pages / etc.) weren't cleaning up socket listeners before calling
next(), causing a memory leak warning. This fix makes sure to run the cleanup before callingnext().v6.0.6Compare Source
Patch Changes
#15965
2dca307Thanks @matthewp! - Fixes client hydration for components imported through Node.js subpath imports (package.json#imports, e.g.#components/*), for example when using the Cloudflare adapter in development.#15770
6102ca2Thanks @jpc-ae! - Updates thecreate astrowelcome message to highlight the graceful dev/preview server quit command rather than the kill process shortcut#15953
7eddf22Thanks @Desel72! - fix(hmr): eagerly recompile on style-only change to prevent stale slots render#15916
5201ed4Thanks @trueberryless! - FixesInferLoaderSchematype inference for content collections defined with a loader that includes aschema#15864
d3c7de9Thanks @florian-lefebvre! - Removes temporary support for Node >=20.19.1 because Stackblitz now uses Node 22 by default#15944
a5e1acdThanks @fkatsuhiro! - Fixes SSR dynamic routes with.htmlextension (e.g.[slug].html.astro) not working#15937
d236245Thanks @ematipico! - Fixes an issue where HMR didn't correctly work on Windows when adding/changing/deleting routes inpages/.#15931
98dfb61Thanks @Strernd! - Fix skew protection query params not being applied to island hydrationcomponent-urlandrenderer-url, and ensure query params are appended safely for asset URLs with existing search/hash parts.Updated dependencies []:
v6.0.5Compare Source
Patch Changes
#15891
b889231Thanks @matthewp! - Fix dev routing forserver:deferislands when adapters opt into handling prerendered routes in Astro core. Server island requests are now treated as prerender-handler eligible so prerendered pages usingprerenderEnvironment: 'node'can load island content without400errors.#15890
765a887Thanks @matthewp! - Fixesastro:actionsvalidation to check resolved routes, so projects using default static output with at least oneprerender = falsepage or endpoint no longer fail during startup.#15884
dcd2c8eThanks @matthewp! - Avoid aMaxListenersExceededWarningduringastro devstartup by increasing the shared Vite watcher listener limit when attaching content server listeners.#15904
23d5244Thanks @jlukic! - Emit thebefore-hydrationscript chunk for theclientVite environment. The chunk was only emitted forprerenderandssrenvironments, causing a 404 when browsers tried to load it. This broke hydration for any integration usinginjectScript('before-hydration', ...), including Lit SSR.#15933
325901eThanks @ematipico! - Fixes an issue where<style>tags inside SVG components weren't correctly tracked when enabling CSP.#15875
c43ef8aThanks @matthewp! - Ensure custom prerenderers are always torn down during build, even whengetStaticPaths()throws.#15887
1861fedThanks @ematipico! - Fixes an issue where the build incorrectly leaked server entrypoint into the client environment, causing adapters to emit warnings during the build.#15888
925252eThanks @matthewp! - Fix a bug whereserver:defercould fail at runtime in prerendered pages for some adapters (including Cloudflare), causing errors likeserverIslandMap?.get is not a function.#15901
07c1002Thanks @delucis! - Fixes JSON schema generation for content collection schemas that have differences between their input and output shapes.#15882
759f946Thanks @matthewp! - FixAstro.url.pathnamefor the root page when usingbuild.format: "file"so it resolves to/index.htmlinstead of/.htmlduring builds.v6.0.4Compare Source
Patch Changes
#15870
920f10bThanks @matthewp! - Prebundleastro/toolbarin dev when custom dev toolbar apps are registered, preventing re-optimization reloads that can hide or break the toolbar.#15876
f47ac53Thanks @ematipico! - FixesredirectToDefaultLocaleproducing a protocol-relative URL (//locale) instead of an absolute path (/locale) whenbaseis'/'.#15767
e0042f7Thanks @matthewp! - Fixes server islands (server:defer) not working when only used in prerendered pages withoutput: 'server'.#15873
35841edThanks @matthewp! - Fix a dev server bug where newly created pages could miss layout-imported CSS until restart.#15874
ce0669dThanks @ematipico! - Fixes a warning when usingprefetchAll#15754
58f1d63Thanks @rururux! - Fixes a bug where a directory at the project root sharing the same name as a page route would cause the dev server to return a 404 instead of serving the page.#15869
76b3a5eThanks @matthewp! - Update the unknown file extension error hint to recommendvite.resolve.noExternal, which is the correct Vite 7 config key.v6.0.3Compare Source
Patch Changes
#15711
b2bd27bThanks @OliverSpeir! - Improves Astro core's dev environment handling for prerendered routes by ensuring route/CSS updates and prerender middleware behavior work correctly across both SSR and prerender environments.This enables integrations that use Astro's prerender dev environment (such as Cloudflare with
prerenderEnvironment: 'node') to get consistent route matching and HMR behavior during development.#15852
1cdaf9fThanks @ematipico! - Fixes a regression where the the routes emitted by theastro:build:donehook didn't have thedistURLarray correctly populated.#15765
ca76ff1Thanks @matthewp! - Hardens server island POST endpoint validation to use own-property checks for improved consistencyv6.0.2Compare Source
Patch Changes
95e12a2Thanks @Princesseuh! - Fixesreturn;syntax not working in the frontmatter correctly in certain contextsv6.0.1Compare Source
Patch Changes
a4c0d0bThanks @matthewp! - Fixesastro addso the tsconfig preview shows the actual pending changes before confirmationv6.0.0Compare Source
Major Changes
#14446
ece667aThanks @florian-lefebvre! - RemovesentryPointsonastro:build:ssrhook (Integration API) - (v6 upgrade guidance)#15535
dfe2e22Thanks @florian-lefebvre! - DeprecatesloadManifest()andloadApp()fromastro/app/node(Adapter API) - (v6 upgrade guidance)#15006
f361730Thanks @florian-lefebvre! - Removes sessiontestdriver - (v6 upgrade guidance)#15461
9f21b24Thanks @florian-lefebvre! - BREAKING CHANGE to the v6 beta Adapter API only: renamesentryTypetoentrypointResolutionand updates possible valuesAstro 6 introduced a way to let adapters have more control over the entrypoint by passing
entryType: 'self'tosetAdapter(). However during beta development, the name was unclear and confusing.entryTypeis now renamed toentrypointResolutionand its possible values are updated:legacy-dynamicbecomesexplicit.selfbecomesauto.If you are building an adapter with v6 beta and specifying
entryType, update it:setAdapter({ // ... - entryType: 'legacy-dynamic' + entrypointResolution: 'explicit' }) setAdapter({ // ... - entryType: 'self' + entrypointResolution: 'auto' })#14426
861b9ccThanks @florian-lefebvre! - Removes the deprecatedemitESMImage()function - (v6 upgrade guidance)#15006
f361730Thanks @florian-lefebvre! - Deprecates session driver string signature - (v6 upgrade guidance)#15180
8780ff2Thanks @Princesseuh! - Adds support for converting SVGs to raster images (PNGs, WebP, etc) to the default Sharp image service - (v6 upgrade guidance)#14446
ece667aThanks @florian-lefebvre! - Removesroutesonastro:build:donehook (Integration API) - ([v6 upgrade guidance](https://docs.astro.build/en/guides/upgrade-to/v6/#removed-routes-on-astrobuilddone-Configuration
📅 Schedule: (in timezone Europe/Copenhagen)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.