Update dependency astro to v7.1.0 [SECURITY] - #476
Merged
Conversation
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
website | a0a6cd4 | Commit Preview URL Branch Preview URL |
Jul 23 2026, 03:46 PM |
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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:
7.0.5→7.1.0Astro: composable
astro/honopipeline bypassessecurity.checkOriginwhenmiddleware()is absent or misorderedGHSA-8mv7-9c27-98vc
More information
Details
Summary
In the composable
astro/honopipeline, thesecurity.checkOriginprotection is only installed by themiddleware()primitive. Theactions()andpages()primitives each dispatch to user code independently, so a pipeline that mounts either primitive before (or without)middleware()will bypass the origin check for those requests.Details
security.checkOrigin(default:true) is intended to reject cross-sitePOST/PUT/PATCH/DELETEform submissions. In the classic pipeline (astro()all-in-one), the check always runs because Astro injects a virtual middleware module even when the user has nosrc/middleware.ts. In the composableastro/honopipeline, the user assembles primitives manually. The check is only installed insidemiddleware()— so:actions()beforemiddleware()allows cross-origin form-encoded action requests to execute before the gate runs. Theexamples/advanced-routingexample and the Cloudflarehonodocs shipped this order.middleware()entirely (reasonable for apps with no custom middleware) silently dropscheckOriginprotection for all on-demand endpoints and pages dispatched throughpages().The attack is a blind write-only CSRF: the attacker can trigger a state-mutating action or endpoint handler using the victim's cookies, but cannot read the cross-origin response body.
Affected versions
Astro
>= 7.0.0when using the composableastro/honopipeline with either:actions()mounted beforemiddleware(), orpages()used withoutmiddleware()The default (non-composable) pipeline is not affected.
Fix
The origin check is now applied at each dispatch sink (
ActionHandler.handleandPagesHandler.handleWithErrorFallback), gated onmanifest.checkOrigin, using the same predicate as the middleware. The check is order-independent and a no-op whenmiddleware()has already run.Fix: https://github.com/withastro/astro/pull/17250
Workaround
Ensure
middleware()is mounted before bothactions()andpages()in the composable pipeline, and that it is always included even when no custom middleware logic is needed:Severity
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:N/SI:L/SA:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Astro: Reflected XSS via unescaped View Transition animation properties
GHSA-4g3v-8h47-v7g6
More information
Details
Summary
Astro's server-side View Transition CSS generator interpolates animation properties into an inline
<style>element without escaping them for the CSS and HTML contexts.An attacker-controlled value passed to an animation property such as
durationcan contain a</style>sequence, terminate the generated style element, and inject arbitrary HTML or JavaScript.This is similar to GHSA-8hv8-536x-4wqp, but exploits a different injection point: unescaped View Transition animation values in a server-generated
<style>element rather than an unescaped slot name in a hydration template.Like GHSA-8hv8-536x-4wqp, exploitation requires an application to pass attacker-controlled data to an Astro API. However, the value is subsequently inserted into the HTML response without context-appropriate escaping by Astro.
Details
packages/astro/src/runtime/server/transition.tsThe generated stylesheet is wrapped in a
<style>element and marked as HTML-safe:Animation properties are added to the stylesheet without escaping:
For string values,
toTimeValue()returns the input unchanged:As a result, a
durationvalue containing</style>can escape from the generated style element.Other
TransitionAnimationproperties, includingeasing,direction,delay,fillMode, andname, are serialized by the same animation builder. The following PoC only relies on the officialfade()helper and itsdurationoption.PoC
Using:
astro@7.0.9@astrojs/node@11.0.2astro.config.mjssrc/pages/index.astroPayload:
open:
The browser interprets
</style>as the end of the generated style element and executes the injected script. An alert dialog is displayed when the page is opened.Impact
An attacker who can control a View Transition animation value can execute arbitrary JavaScript in the origin of the affected Astro application.
The query-based reflected XSS scenario affects on-demand/server-rendered routes, such as:
output: "server";export const prerender = false;Successful exploitation may allow access to sensitive page data and authenticated actions available to the victim.
Suggested Fix
Animation values should be serialized using context-appropriate CSS escaping or validation before being added to the generated stylesheet.
Additionally, content inserted into a raw
<style>element must not be able to contain an HTML end-tag sequence such as</style>. The final generated CSS should be made safe for the HTML raw-text context before it is passed tomarkHTMLString().Severity
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:L/SI:L/SA:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Astro: XSS via unescaped spread attribute names in renderHTMLElement (incomplete fix for CVE-2026-54298)
CVE-2026-59729 / GHSA-f48w-9m4c-m7f5
More information
Details
Summary
The fix for CVE-2026-54298 (GHSA-jrpj-wcv7-9fh9) added an
INVALID_ATTR_NAME_CHARguard toaddAttribute()so that spread-prop attribute names containing"' >/=or whitespace are dropped. A second attribute-rendering path,renderHTMLElement()inpackages/astro/src/runtime/server/render/dom.ts, has its own inline attribute loop that does not go throughaddAttribute()and was not updated. It interpolates the attribute name unescaped and only escapes the value, so untrusted prop keys spread onto a native-HTMLElement-subclass component can still break out of the attribute context, resulting in XSS.Details
renderHTMLElementbuilds attributes directly:The attribute name (
attr) is interpolated raw; only the value is escaped viatoAttributeString. By contrast, the hardenedaddAttributeinutil.tsrejects invalid names:renderHTMLElementis reached fromcomponent.tswhen the component is a nativeHTMLElementsubclass:where
_propscarries spread props verbatim.Reachability
The branch only runs when
typeof HTMLElement === 'function'at SSR time. In default Node SSRHTMLElementisundefined, so the branch is dead. It becomes reachable when the SSR runtime exposes a globalHTMLElement(Deno, Bun with a DOM shim, or jsdom/happy-dom in Node) and a class extendingHTMLElementis used directly as an Astro component that receives untrusted-keyed spread props.Proof of Concept
Given malicious spread props:
addAttribute(post-fix) →<my-el></my-el>(key stripped — safe)renderHTMLElement→<my-el onmouseover=alert(document.domain) x="y" x><script>alert(1)</script>="z"></my-el>(handler +<script>injected — XSS)Equivalent Astro template, served by an SSR runtime that defines a global
HTMLElement:Impact
Cross-site scripting (CWE-79) via attribute-name breakout — the same vulnerability class as CVE-2026-54298, in a code path its fix did not cover. An attacker who controls the keys of an object spread onto a native-
HTMLElement-subclass component can inject arbitrary event-handler attributes or sibling elements (including<script>) into the SSR output. Reachability is constrained by the runtime and component preconditions described above.Severity
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Release Notes
withastro/astro (astro)
v7.1.0Compare Source
Minor Changes
#17302
5f4dc03Thanks @astrobot-houston! - Adds a newdeferRenderoption to theglob()content loaderWhen set to
true, renderable entries (such as Markdown) are not rendered during content sync. Instead, rendering is deferred until the entry is actually rendered in a page, using the same on-demand path that.mdxfiles already use.This reduces memory usage during
astro buildfor large collections whose rendered output is much larger than the source — for example, Markdown that uses heavy rehype plugins likerehype-katex. Such builds could previously run out of memory while storing the eagerly-rendered HTML for every entry.By default
deferRenderisfalse, preserving the existing behavior of rendering entries eagerly during sync so their rendered HTML can be cached across builds.#17296
30698a2Thanks @ematipico! - Adds a new experimentalcollectionStorageoption for controlling how the content layer persists its data storeBy default, Astro serializes the entire content layer data store to a single file (
.astro/data-store.json). For very large content collections, this file can grow large enough to hit platform file-size limits.Set
experimental.collectionStorage: 'chunked'to instead split the data store across many smaller, content-addressed files inside a.astro/data-store/directory, described by a manifest:Because each part file is named by a hash of its contents, unchanged parts keep the same name across builds and are not rewritten, and identical parts are deduplicated. The default value is
'single-file', which preserves the current behavior.#17214
44c4989Thanks @ematipico! - Adds support for the more specific CSP directivesscript-src-elem,script-src-attr,style-src-elem, andstyle-src-attrthrough a newkindoption.Previously,
CSPwas only scoped to genericscript-src/style-srcdirectives. Now each source or hash can be scoped to a narrower directive — for example, to allow inlinestyleattributes (such as those fromdefine:varsor Shiki) without loosening the policy for your<style>and<link>elements.Scoping sources and hashes in your config
Each entry in
resourcesandhashescan be an object with akindproperty. Depending on whether you usescriptDirectiveorstyleDirective,"element"targetsscript-src-elemorstyle-src-elem,"attribute"targetsscript-src-attrorstyle-src-attr, and"default"(the same as a bare string or hash) targetsscript-srcorstyle-src.Scoping at runtime
The same
kindoption is available on the runtime CSP API, where the existing methods now also accept an object:#17258
84814d4Thanks @astrobot-houston! - Adds a newformat()option to thepaginateutility. Theformat()option is a function that accepts the current URL of the page, and returns a new URL.For example, when your host only supports URLs using the
.htmlextension, you can useformat()to add it to the generated URLs:#17331
7db6420Thanks @matthewp! - Adds a--ignore-lockflag toastro devfor starting a dev server without checking or writing the lock file, so it can run alongside an already-running dev server for the same project.The new instance is not tracked by
astro dev stop,astro dev status, orastro dev logs.--ignore-lockcannot be combined with--background(or an auto-detected AI agent environment, which runs dev servers in the background automatically) or--force, since those rely on the lock file.#17389
16de021Thanks @florian-lefebvre! - Allows passing URL entrypoints when configuring the loggerMatching other APIs like session drivers or font providers, the logger entrypoint can now be a URL:
Patch Changes
#17332
4407483Thanks @astrobot-houston! - Fixes the JSON logger crashing withprocess is not definedin non-Node runtimes like Cloudflare's workerd. The JSON logger now usesconsole.log/console.errorinstead ofprocess.stdout/process.stderr, matching the pattern already used by the console logger.#17391
186a1e7Thanks @florian-lefebvre! - Fixes a case where an integration could not update the logger withupdateConfig()#17394
d9f99e1Thanks @matthewp! - Fixes element-specific CSP directives to preserve the existing behavior of configured script and style resources#17374
b2d1b3eThanks @astrobot-houston! - Fixes dev server returning 404 for?urlimported assets when accessed via browser navigation#17390
ed71eafThanks @florian-lefebvre! - Removes an unused and undocumented generic from theAstroLoggerDestinationtype#17393
092da56Thanks @matthewp! - Hardens generated transition styles, development metadata, and server island URLs when embedding dynamic valuesv7.0.9Compare Source
Patch Changes
#17286
a249317Thanks @astrobot-houston! - Fixes the first browser visit afterastro devstarts triggering an immediate full page reload#17369
a94d4a5Thanks @adamchal! - Fixes an issue where a client island could permanently fail to hydrate if the first attempt to load its component failed. Islands now reliably recover from transient import failures, which previously did not work for React components duringastro dev.v7.0.8Compare Source
Patch Changes
#17363
3f4efc5Thanks @astrobot-houston! - Fixesastro preview --opennot opening a browser when using an adapter with a custom preview entrypoint, such as@astrojs/cloudflare#17313
e2e319dThanks @ronits2407! - Exposes theAstroRuntimeLoggerinterface to allow users to properly type the logger functions at runtime.#17328
025cc74Thanks @matthewp! - Fixesastro dev --forcenot replacing an already-running dev server#17353
2bba277Thanks @ematipico! - Updates the Astro compiler to the latest version, which fixes many regressions. Refer to the changelog for more details.#17344
79a41e0Thanks @adamchal! - Improves rendering performance for pages with many component instances, such as repeated MDX<Content />components.Updated dependencies [
64b0d66]:v7.0.7Compare Source
Patch Changes
#17318
23a4120Thanks @astrobot-houston! - Fixes CSS module scoped-name hash mismatch inastro devwhen usingvite.css.transformer: 'lightningcss'with content collections. Previously, a component importing a CSS module and rendered via content collectionrender()would get different class name hashes in the element and the injected<style>tag, causing styles not to apply.#17323
4298883Thanks @ematipico! - Fixes a dev server memory leak which caused Node.js to emit warnings in the console.#17323
4298883Thanks @ematipico! - Fixes a dev server crash when a.htmlor/index.htmlsuffixed request (such as thosenetlify devprobes as pretty-URL fallbacks) matched a dynamic endpoint route, causing aTypeError: Missing parametererror#17325
cebc404Thanks @astrobot-houston! - Fixes a bug where CSS@importrules could end up mid-stylesheet after inline CSS chunks were merged during build, causing browsers to silently ignore them#17323
4298883Thanks @ematipico! - Fixes a build regression that could leave unresolved preload markers in inlined scripts with external dynamic importsUpdated dependencies [
4298883,4298883]:v7.0.6Compare Source
Patch Changes
#17261
79aa99cThanks @astrobot-houston! - Fixes a false deprecation warning formarkdown.gfmandmarkdown.smartypantswhen using the Container API#17247
f94280dThanks @chatman-media! - Fixes route generation throwing "Missing parameter" (or silently dropping the segment) when a dynamic param's value is0. The generator used truthy checks instead of checking forundefined, sopaginate(posts, { params: { categoryId: 0 } })would crash even though0is a perfectly valid param value.#17278
6f11739Thanks @astrobot-houston! - Fixes missing CSS for virtual style modules (e.g., responsive image layout styles) in dev mode when JavaScript is disabled#17250
0b30b35Thanks @matthewp! - Fixes thesecurity.checkOrigincheck so it is applied consistently to Astro Actions and on-demand endpoints, regardless of how the request pipeline is composed. Previously, the origin check could be skipped in the composableastro/honopipeline depending on the order of themiddleware()primitive (or when it was omitted).#17274
8c3579bThanks @astrobot-houston! - Fixes missingrender()type overload for live collection entries. Previously, callingrender()on aLiveDataEntryproduced a TypeScript error when using onlylive.config.tswithout acontent.config.ts.#17257
4208297Thanks @astrobot-houston! - Fixesastro checkfailing to find@astrojs/checkandtypescriptwhen astro is installed in a directory outside the project tree (e.g. pnpm virtual store)#17272
b428648Thanks @matthewp! - Fixes island component paths so that extensionless imports (e.g.import { Counter } from '../components/Counter') resolve to the real file on disk, matching Vite's extension order and directoryindexresolution. This makes theinclude/excludeoptions of JSX renderer integrations (React, Preact, Solid) match components imported without a file extension, and removes the spurious React 19 "Invalid hook call" warning logged on every request in dev whenincludewas set alongside another JSX renderer#17279
2aeaa44Thanks @astrobot-houston! - Fixes a bug where<Picture inferSize>with a remote image could fail withFailedToFetchRemoteImageDimensionswhen the image server rate-limits requests (e.g. HTTP 429). Remote dimensions are now resolved once per render instead of once per output format.#17251
5240e26Thanks @matthewp! - Hardens the handling of attribute rendering when using with custom elements.#17248
429bd62Thanks @astrobot-houston! - Fixes a crash when using Astro'sgetViteConfigwith Vitest browser mode (e.g., Storybook vitest runner). Astro now skips dev server setup inside Vitest, preventing errors.#17260
14524c0Thanks @matthewp! - Fixes a regression where a<script>inside a component rendered throughAstro.slots.render()was hoisted out of its original position instead of staying next to its component contentUpdated dependencies [
eb6f97e]:Configuration
📅 Schedule: (UTC)
🚦 Automerge: Enabled.
♻ Rebasing: Whenever PR is behind base branch, 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.