fix(deps): update dependency astro to v6 [security]#199
Open
renovate[bot] wants to merge 1 commit intomainfrom
Open
fix(deps): update dependency astro to v6 [security]#199renovate[bot] wants to merge 1 commit intomainfrom
renovate[bot] wants to merge 1 commit intomainfrom
Conversation
3a3e2a4 to
19e2fc2
Compare
19e2fc2 to
8f1c3e9
Compare
8f1c3e9 to
7305175
Compare
7305175 to
27db9cd
Compare
27db9cd to
b154c7f
Compare
b154c7f to
b031113
Compare
b031113 to
af27f53
Compare
50f2855 to
f8c0091
Compare
f1017a1 to
65c85a8
Compare
65c85a8 to
4ba6195
Compare
4ba6195 to
54f3ba9
Compare
54f3ba9 to
57fb995
Compare
6ee4287 to
87d9054
Compare
87d9054 to
e0f3012
Compare
e0f3012 to
b7663e0
Compare
b7663e0 to
c518c47
Compare
c518c47 to
5ae86f7
Compare
5ae86f7 to
f119873
Compare
f119873 to
74a9cd8
Compare
74a9cd8 to
887786e
Compare
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:
^5.12.0→^6.0.0Astros's duplicate trailing slash feature leads to an open redirection security issue
CVE-2025-54793 / GHSA-cq8c-xv66-36gw
More information
Details
Summary
There is an Open Redirection vulnerability in the trailing slash redirection logic when handling paths with double slashes. This allows an attacker to redirect users to arbitrary external domains by crafting URLs such as
https://mydomain.com//malicious-site.com/. This increases the risk of phishing and other social engineering attacks.This affects Astro >=5.2.0 sites that use on-demand rendering (SSR) with the Node or Cloudflare adapter. It does not affect static sites, or sites deployed to Netlify or Vercel.
Background
Astro performs automatic redirection to the canonical URL, either adding or removing trailing slashes according to the value of the
trailingSlashconfiguration option. It follows the following rules:trailingSlashis set to"never",https://example.com/page/will redirect tohttps://example.com/pagetrailingSlashis set to"always",https://example.com/pagewill redirect tohttps://example.com/page/It also collapses multiple trailing slashes, according to the following rules:
trailingSlashis set to"always"or"ignore"(the default),https://example.com/page//will redirect tohttps://example.com/page/trailingSlashis set to"never",https://example.com/page//will redirect tohttps://example.com/pageIt does this by returning a
301redirect to the target path. The vulnerability occurs because it uses a relative path for the redirect. To redirect fromhttps://example.com/pagetohttps://example.com/page/, it sending a 301 response with the headerLocation: /page/. The browser resolves this URL relative to the original page URL and redirects tohttps://example.com/page/Details
The vulnerability occurs if the target path starts with
//. A request forhttps://example.com//pagewill send the headerLocation: //page/. The browser interprets this as a protocol-relative URL, so instead of redirecting tohttps://example.com//page/, it will attempt to redirect tohttps://page/. This is unlikely to resolve, but by crafting a URL in the formhttps://example.com//target.domain/subpath, it will send the headerLocation: //target.domain/subpath/, which the browser translates as a redirect tohttps://target.domain/subpath/. The subpath part is required because otherwise Astro will interpret/target.domainas a file download, which skips trailing slash handling.This leads to an Open Redirect vulnerability.
The URL needed to trigger the vulnerability varies according to the
trailingSlashsetting.trailingSlashis set to"never", a URL in the formhttps://example.com//target.domain/subpath/trailingSlashis set to"always", a URL in the formhttps://example.com//target.domain/subpathhttps://example.com//target.domain/subpath//Impact
This is classified as an Open Redirection vulnerability (CWE-601). It affects any user who clicks on a specially crafted link pointing to the affected domain. Since the domain appears legitimate, victims may be tricked into trusting the redirected page, leading to possible credential theft, malware distribution, or other phishing-related attacks.
No authentication is required to exploit this vulnerability. Any unauthenticated user can trigger the redirect by clicking a malicious link.
Mitigation
Usrs can test if your site is affected by visiting
https://yoursite.com//docs.astro.build/en//. If a user is redirected to the Astro docs then their site is affected and must be updated.Upgrade to Astro 5.12.8. To mitigate at the network level, block outgoing redirect responses with a
Locationheader value that starts with//.Severity
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N/E:PReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Astro's
X-Forwarded-Hostis reflected without validationCVE-2025-61925 / GHSA-5ff5-9fcw-vg88
More information
Details
Summary
When running Astro in on-demand rendering mode using a adapter such as the node adapter it is possible to maliciously send an
X-Forwarded-Hostheader that is reflected when using the recommendedAstro.urlproperty as there is no validation that the value is safe.Details
Astro reflects the value in
X-Forwarded-Hostin output when usingAstro.urlwithout any validation.It is common for web servers such as nginx to route requests via the
Hostheader, and forward on other request headers. As such as malicious request can be sent with both aHostheader and anX-Forwarded-Hostheader where the values do not match and theX-Forwarded-Hostheader is malicious. Astro will then return the malicious value.This could result in any usages of the
Astro.urlvalue in code being manipulated by a request. For example if a user follows guidance and usesAstro.urlfor a canonical link the canonical link can be manipulated to another site. It is not impossible to imagine that the value could also be used as a login/registration or other form URL as well, resulting in potential redirecting of login credentials to a malicious party.As this is a per-request attack vector the surface area would only be to the malicious user until one considers that having a caching proxy is a common setup, in which case any page which is cached could persist the malicious value for subsequent users.
Many other frameworks have an allowlist of domains to validate against, or do not have a case where the headers are reflected to avoid such issues.
PoC
nvm useyarn run buildnode ./dist/server/entry.mjscurl --location 'http://localhost:4321/' --header 'X-Forwarded-Host: www.evil.com' --header 'Host: www.example.com'X-Forwarded-HostheaderFor the more advanced / dangerous attack vector deploy the application behind a caching proxy, e.g. Cloudflare, set a non-zero cache time, perform the above
curlrequest a few times to establish a cache, then perform the request without the malicious headers and observe that the malicious data is persisted.Impact
This could affect anyone using Astro in an on-demand/dynamic rendering mode behind a caching proxy.
Severity
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:LReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Astro development server error page is vulnerable to reflected Cross-site Scripting
CVE-2025-64745 / GHSA-w2vj-39qv-7vh7
More information
Details
Summary
A Reflected Cross-Site Scripting (XSS) vulnerability exists in Astro's development server error pages when the
trailingSlashconfiguration option is used. An attacker can inject arbitrary JavaScript code that executes in the victim's browser context by crafting a malicious URL. While this vulnerability only affects the development server and not production builds, it could be exploited to compromise developer environments through social engineering or malicious links.Details
Vulnerability Location
https://github.com/withastro/astro/blob/5bc37fd5cade62f753aef66efdf40f982379029a/packages/astro/src/template/4xx.ts#L133-L149
Root Cause
The vulnerability was introduced in commit
536175528(PR #12994) , as part of a feature to "redirect trailing slashes on on-demand rendered pages." The feature added a helpful 404 error page in development mode to alert developers of trailing slash mismatches.Issue: The
correctedvariable, which is derived from the user-controlledpathnameparameter, is directly interpolated into the HTML without proper escaping. While thepathnamevariable itself is escaped elsewhere in the same file (line 114:escape(pathname)), thecorrectedvariable is not sanitized before being inserted into both thehrefattribute and the link text.Attack Vector
When a developer has configured
trailingSlashto'always'or'never'and visits a URL with a mismatched trailing slash, the development server returns a 404 page containing the vulnerable template. An attacker can craft a URL with JavaScript payloads that will be executed when the page is rendered.PoC
Local Testing (localhost)
Basic vulnerability verification in local development environment
Show details
astro.config.mjs:package.json:{ "name": "astro-xss-poc-victim", "version": "0.1.0", "scripts": { "dev": "astro dev" }, "dependencies": { "astro": "5.15.5" } }Start the development server:
Access the following malicious URL depending on your configuration:
For
trailingSlash: 'never'(requires trailing slash):For
trailingSlash: 'always'(no trailing slash):When accessing the malicious URL:
alert(document.domain)) executes in the browserRemote Testing (ngrok)
Reproduce realistic attack scenario via external malicious link
Show details
Prerequisites: ngrok account and authtoken configured (
ngrok config add-authtoken <key>)Setup and Execution:
When a remote user accesses either of the generated attack URLs:
alert(document.domain)) executes in the user's browserBoth URL patterns work depending on your
trailingSlashconfiguration ('never' or 'always').Impact
This only affects the development server. Risk depends on how and where the dev server is exposed.
Security impact
localhostendpoints or dev tools depending on browser policies.Attack scenarios
Severity
CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:C/C:L/I:N/A:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Astro vulnerable to URL manipulation via headers, leading to middleware and CVE-2025-61925 bypass
CVE-2025-64525 / GHSA-hr2q-hp5q-x767
More information
Details
Summary
In impacted versions of Astro using on-demand rendering, request headers
x-forwarded-protoandx-forwarded-portare insecurely used, without sanitization, to build the URL. This has several consequences the most important of which are:x-forwarded-proto)x-forwarded-proto)Details
The
x-forwarded-protoandx-forwarded-portheaders are used without sanitization in two parts of the Astro server code. The most important is in thecreateRequest()function. Any configuration, including the default one, is affected:https://github.com/withastro/astro/blob/970ac0f51172e1e6bff4440516a851e725ac3097/packages/astro/src/core/app/node.ts#L97
https://github.com/withastro/astro/blob/970ac0f51172e1e6bff4440516a851e725ac3097/packages/astro/src/core/app/node.ts#L121
These header values are then used directly to construct URLs.
By injecting a payload at the protocol level during URL creation (via the
x-forwarded-protoheader), the entire URL can be rewritten, including the host, port and path, and then pass the rest of the URL, the real hostname and path, as a query so that it doesn't affect (re)routing.If the following header value is injected when requesting the path
/ssr:The complete URL that will be created is:
https://www.malicious-url.com/?tank=://localhost/ssrAs a reminder, URLs are created like this:
The value is injected at the beginning of the string (
${protocol}), and ends with a query?tank=whose value is the rest of the string,://${hostnamePort}${req.url}.This way there is control over the routing without affecting the path, and the URL can be manipulated arbitrarily. This behavior can be exploited in various ways, as will be seen in the PoC section.
The same logic applies to
x-forwarded-port, with a few differences.PoC
The PoC will be tested with a minimal repository:
2.16.0)/ssr), the other simulating an admin page (/admin) protected by a middlewareDownload the PoC repository
Middleware-based protected route bypass - x-forwarded-proto only
The middleware has been configured to protect the
/adminroute based on the official documentation:When tryint to access
/adminthe attacker is naturally redirected :The attackr can bypass the middleware path check using a malicious header value:
curl -i -H "x-forwarded-proto: x:admin?" http://localhost:4321/adminHow is this possible?
Here, with the payload
x:admin?, the attacker can use the URL API parser to their advantage:x:is considered the protocol//, the parser considers there to be no authority, and everything before the?character is therefore considered part of the path:adminDuring a path-based middleware check, the path value begins with a
/:context.url.pathname === "/admin". However, this is not the case with this payload;context.url.pathname === "admin", the absence of a slash satisfies both the middleware check and the router and consequently allows us to bypass the protection and access the page.SSRF
As seen, the request URL is built from untrusted input via the
x-forwarded-protocolheader, if it turns out that this URL is subsequently used to perform external network calls, for an API for example, this allows an attacker to supply a malicious URL that the server will fetch, resulting in server-side request forgery (SSRF).Example of code reusing the "origin" URL, concatenating it to the API endpoint :
DoS via cache poisoning
If a CDN is present, it is possible to force the caching of bad pages/resources, or 404 pages on the application routes, rendering the application unusable.
A

404cab be forced, causing an error on the/ssrpage like this :curl -i -H "x-forwarded-proto: https://localhost/vulnerable?" http://localhost:4321/ssrSame logic applies to
x-forwarded-port:curl -i -H "x-forwarded-port: /vulnerable?" http://localhost:4321/ssrHow is this possible?
The router sees the request for the path
/vulnerable, which does not exist, and therefore returns a404, while the potential CDN sees/ssrand can then cache the404response, consequently serving it to all users requesting the path/ssr.URL pollution
The exploitability of the following is also contingent on the presence of a CDN, and is therefore cache poisoning.
If the value of
request.urlis used to create links within the page, this can lead to Stored XSS withx-forwarded-protoand the following value:results in the following URL object:
It is also possible to inject any link, always, if the value of
request.urlis used on the server side to create links.The attacker is more limited with
x-forwarded-portIf the value of
request.urlis used to create links within the page, this can lead to broken links, with the header and the following value:Example of an Astro website:

WAF bypass
For this section, Astro invites users to read previous research on the React-Router/Remix framework, in the section "Exploitation - WAF bypass and escalations". This research deals with a similar case, the difference being that the vulnerable header was
x-forwarded-hostin their case:https://zhero-web-sec.github.io/research-and-things/react-router-and-the-remixed-path
Note: A section addressing DoS attacks via cache poisoning using the same vector was also included there.
CVE-2025-61925 complete bypass
It is possible to completely bypass the vulnerability patch related to the
X-Forwarded-Hostheader.By sending
x-forwarded-hostwith an empty value, theforwardedHostnamevariable is assigned an empty string. Then, during the subsequent check, the condition fails becauseforwardedHostnamereturnsfalse, its value being an empty string:Consequently, the implemented check is bypassed. From this point on, since the request has no
host(its value being an empty string), the path value is retrieved by the URL parser to set it as thehost. This is because thehttp/httpsschemes are considered special schemes by the WHATWG URL Standard Specification, requiring anauthority state.From there, the following request on the example SSR application (astro repo) yields an SSRF:

empty
x-forwarded-host+ the targethostin the pathCredits
Severity
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:LReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Astro Development Server has Arbitrary Local File Read
CVE-2025-64757 / GHSA-x3h8-62x9-952g
More information
Details
Summary
A vulnerability has been identified in the Astro framework's development server that allows arbitrary local file read access through the image optimization endpoint. The vulnerability affects Astro development environments and allows remote attackers to read any image file accessible to the Node.js process on the host system.
Details
/packages/astro/src/assets/endpoint/node.tsThe vulnerability exists in the Node.js image endpoint handler used during development mode. The endpoint accepts an
hrefparameter that specifies the path to an image file. In development mode, this parameter is processed without adequate path validation, allowing attackers to specify absolute file paths.Vulnerable Code Location:
packages/astro/src/assets/endpoint/node.tsThe development branch bypasses the security checks that exist in the production code path, which validates that file paths are within the allowed assets directory.
PoC
Attack Prerequisites
astro dev)/_imageendpoint must be accessible to the attackerExploit Steps
Start Astro Development Server:
astro dev # Typically runs on http://localhost:4321Craft Malicious Request:
Example Attack:
curl "http://localhost:4321/_image?href=/%2FSystem%2FLibrary%2FImage%20Capture%2FAutomatic%20Tasks%2FMakePDF.app%2FContents%2FResources%2F0blank.jpg&w=100&h=100&f=png" -o stolen.pngDemonstration Results
Test Environment: macOS with Astro v5.13.3
Successful Exploitation:
/System/Library/Image Capture/Automatic Tasks/MakePDF.app/Contents/Resources/0blank.jpgstolen-image.pngcontaining processed system imageAttack Payload:
Server Response:
Impact
Confidentiality Impact: HIGH
Integrity Impact: NONE
Availability Impact: NONE
Affected Components
Primary Component
packages/astro/src/assets/endpoint/node.tsloadLocalImage()Secondary Components
packages/astro/src/assets/endpoint/generic.tsSeverity
CVSS:3.1/AV:A/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Astro vulnerable to reflected XSS via the server islands feature
CVE-2025-64764 / GHSA-wrwg-2hg8-v723
More information
Details
Summary
After some research it appears that it is possible to obtain a reflected XSS when the server islands feature is used in the targeted application, regardless of what was intended by the component template(s).
Details
Server islands run in their own isolated context outside of the page request and use the following pattern path to hydrate the page:
/_server-islands/[name]. These paths can be called via GET or POST and use three parameters:e: component to exportp: the transmitted properties, encrypteds: for the slotsSlots are placeholders for external HTML content, and therefore allow, by default, the injection of code if the component template supports it, nothing exceptional in principle, just a feature.
This is where it becomes problematic: it is possible, independently of the component template used, even if it is completely empty, to inject a slot containing an XSS payload, whose parent is a tag whose name is is the absolute path of the island file. Enabling reflected XSS on any application, regardless of the component templates used, provided that the server islands is used at least once.
How ?
By default, when a call is made to the endpoint
/_server-islands/[name], the value of the parametereisdefault, pointing to a function exported by the component's module.Upon further investigation, we find that two other values are possible for the component export (param
e) in a typical configuration:urlandfile.filereturns a string value corresponding to the absolute path of the island file. Since the value is of typestring, it fulfills the following condition and leads to this code block:An entire template is created, completely independently, and then returned:
childSlots, the value provided to thesparameter, is injected as a childAll of this is done using
markHTMLString. This allows the injection of any XSS payload, even if the component template intended by the application is initially empty or does not provide for the use of slots.Proof of concept
For our Proof of Concept (PoC), we will use a minimal repository:
Download the PoC repository
Access the following URL and note the opening of the popup, demonstrating the reflected XSS:
http://localhost:4321/_server-islands/ServerTime?e=file&p=&s={%22zhero%22:%22%3Cimg%20src=x%20onerror=alert(0)%3E%22}
The value of the parameter
smust be in JSON format and the payload must be injected at the value level, not the key level :Despite the initial template being empty, it is created because the value of the URL parameter
eis set tofile, as explained earlier. The parent tag is the name of the component's internal route, and its child is the value of the key "zhero" (the name doesn't matter) of the URL parameters.Credits
Severity
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:H/A:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Astro's middleware authentication checks based on url.pathname can be bypassed via url encoded values
CVE-2025-64765 / GHSA-ggxq-hp9w-j794
More information
Details
A mismatch exists between how Astro normalizes request paths for routing/rendering and how the application’s middleware reads the path for validation checks. Astro internally applies
decodeURI()to determine which route to render, while the middleware usescontext.url.pathnamewithout applying the same normalization (decodeURI).This discrepancy may allow attackers to reach protected routes (e.g., /admin) using encoded path variants that pass routing but bypass validation checks.
https://github.com/withastro/astro/blob/ebc4b1cde82c76076d5d673b5b70f94be2c066f3/packages/astro/src/vite-plugin-astro-server/request.ts#L40-L44
Consider an application having the following middleware code:
context.url.pathnameis validated , if it's equal to/admintheisAuthedproperty must be true for the next() method to be called. The same example can be found in the official docs https://docs.astro.build/en/guides/authentication/context.url.pathnamereturns the raw version which is/%61adminwhile pathname which is used for routing/rendering/admin, this creates a path normalization mismatch.By sending the following request, it's possible to bypass the middleware check
Remediation
Ensure middleware context has the same normalized pathname value that Astro uses internally, because any difference could allow it to bypass such checks. In short maybe something like this
pathname = decodeURI(url.pathname); } // Add config.base back to url before passing it to SSR - url.pathname = removeTrailingForwardSlash(config.base) + url.pathname; + url.pathname = removeTrailingForwardSlash(config.base) + decodeURI(url.pathname);Thank you, let @Sudistark know if any more info is needed. Happy to help :)
Severity
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Astro Cloudflare adapter has Stored Cross-site Scripting vulnerability in /_image endpoint
CVE-2025-65019 / GHSA-fvmw-cj7j-j39q
More information
Details
Summary
A Cross-Site Scripting (XSS) vulnerability exists in Astro when using the @astrojs/cloudflare adapter with
output: 'server'. The built-in image optimization endpoint (/_image) usesisRemoteAllowed()from Astro’s internal helpers, which unconditionally allowsdata:URLs. When the endpoint receives a validdata:URL pointing to a malicious SVG containing JavaScript, and the Cloudflare-specific implementation performs a 302 redirect back to the originaldata:URL, the browser directly executes the embedded JavaScript. This completely bypasses any domain allow-listing (image.domains/image.remotePatterns) and typical Content Security Policy mitigations.Affected Versions
@astrojs/cloudflare≤ 12.6.10 (and likely all previous versions)output: 'server'and the Cloudflare adapterRoot Cause – Vulnerable Code
File:
node_modules/@​astrojs/internal-helpers/src/remote.tsIn the Cloudflare adapter, the
/_imageendpoint contains logic similar to:Because
data:URLs are considered “allowed”, a request such as:https://example.com/_image?href=data:image/svg+xml;base64,PHN2Zy... (base64-encoded malicious SVG)triggers a 302 redirect directly to the
data:URL, causing the browser to render and execute the malicious JavaScript inside the SVG.Proof of Concept (PoC)
output: 'server').(Base64 decodes to:
<svg xmlns="http://www.w3.org/2000/svg"><script>alert('zomasec')</script></svg>)data:URL → browser executes the<script>→alert()fires.Impact
image.domains/image.remotePatternsconfiguration entirelySafe vs Vulnerable Behavior
Other Astro adapters (Node, Vercel, etc.) typically proxy and rasterize SVGs, stripping JavaScript. The Cloudflare adapter currently redirects to remote resources (including
data:URLs), making it uniquely vulnerable.References
data:URL bypass in WordPress: CVE-2025-2575Severity
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Astro allows unauthorized third-party images in _image endpoint
CVE-2025-55303 / GHSA-xf8x-j4p2-f749
More information
Details
Summary
In affected versions of
astro, the image optimization endpoint in projects deployed with on-demand rendering allows images from unauthorized third-party domains to be served.Details
On-demand rendered sites built with Astro include an
/_imageendpoint which returns optimized versions of images.The
/_imageendpoint is restricted to processing local images bundled with the site and also supports remote images from domains the site developer has manually authorized (using theimage.domainsorimage.remotePatternsoptions).However, a bug in impacted versions of
astroallows an attacker to bypass the third-party domain restrictions by using a protocol-relative URL as the image source, e.g./_image?href=//example.com/image.png.Proof of Concept
Create a new minimal Astro project (
astro@5.13.0).Configure it to use the Node adapter (
@astrojs/node@9.1.0— newer versions are not impacted):Build the site by running
astro build.Run the server, e.g. with
astro preview.Append
/_image?href=//placehold.co/600x400to the preview URL, e.g. http://localhost:4321/_image?href=//placehold.co/600x400The site will serve the image from the unauthorized
placehold.coorigin.Impact
Allows a non-authorized third-party to create URLs on an impacted site’s origin that serve unauthorized image content.
In the case of SVG images, this could include the risk of cross-site scripting (XSS) if a user followed a link to a maliciously crafted SVG.
Severity
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:H/SI:H/SA:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Astro has an Authentication Bypass via Double URL Encoding, a bypass for CVE-2025-64765
CVE-2025-66202 / GHSA-whqg-ppgf-wp8c
More information
Details
Authentication Bypass via Double URL Encoding in Astro
Bypass for CVE-2025-64765 / GHSA-ggxq-hp9w-j794
Summary
A double URL encoding bypass allows any unauthenticated attacker to bypass path-based authentication checks in Astro middleware, granting unauthorized access to protected routes. While the original CVE-2025-64765 (single URL encoding) was fixed in v5.15.8, the fix is insufficient as it only decodes once. By using double-encoded URLs like
/%2561dmininstead of/%61dmin, attackers can still bypass authentication and access protected resources such as/admin,/api/internal, or any route protected by middleware pathname checks.Fix
A more secure fix is just decoding once, then if the request has a %xx format, return a 400 error by using something like :
Severity
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Astro: 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