CVE-2025-65019
Medium · 5.4Astro Cloudflare adapter has Stored Cross Site Scripting vulnerability in /_image endpoint
CVSS
5.4
EPSS
0.3%
Published
Nov 19, 2025
CISA due date
—
The record
**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`) uses `isRemoteAllowed()` from Astro’s internal helpers, which **unconditionally allows `data:` URLs**. When the endpoint receives a valid `data:` URL pointing to a malicious SVG containing JavaScript, and the Cloudflare-specific implementation performs a **302 redirect back to the original `data:` 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) - Astro ≥ 4.x when used with `output: 'server'` and the Cloudflare adapter **Root Cause – Vulnerable Code** File: `node_modules/@astrojs/internal-helpers/src/remote.ts` ```ts export function isRemoteAllowed(src: string, ...): boolean { if (!URL.canParse(src)) { return false; } const url = new URL(src); // Data URLs are always allowed if (url.protocol === 'data:') { return true; } // Non-http(s) protocols are never allowed if (!['http:', 'https:'].includes(url.protocol)) { return false; } // ... further http/https allow-list checks } ``` In the **Cloudflare adapter**, the `/_image` endpoint contains logic similar to: ```ts const href = ctx.url.searchParams.get('href'); if (!href) { // return error } if (isRemotePath(href)) { if (isRemoteAllowed(href, imageConfig) === false) { // return error } else { //redirect to return the image return Response.redirect(href, 302); } } ``` 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)** 1. Create a minimal Astro project with Cloudflare adapter (`output: 'server'`). 2. Deploy to Cloudflare Pages or Workers. 3. Request the image endpoint with the following payload:
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|---|---|---|
| npm | astro | 0 | 5.15.9 |
Related vulnerabilities
- GHSA-fvmw-cj7j-j39q Astro Cloudflare adapter has Stored Cross-site Scripting vulnerability in /_image endpoint Same vulnerability
- CVE-2026-54298 Astro is a web framework. Also affects astro
- CVE-2026-54299 Astro is a web framework. Also affects astro
- CVE-2026-50146 Astro is a web framework. Also affects astro
- GHSA-jrpj-wcv7-9fh9 Astro: XSS via Unescaped Attribute Names in Spread Props Also affects astro
- GHSA-2pvr-wf23-7pc7 Astro: Host header SSRF in prerendered error page fetch Also affects astro
- GHSA-8hv8-536x-4wqp Astro: Reflected XSS via unescaped slot name Also affects astro
- CVE-2026-45028 Astro is a web framework. Also affects astro