Lookup for vulnerable packages by Package URL.
| Purl | pkg:npm/%40astrojs/cloudflare@0.0.0-cf-10-solid-20240329084913 |
| Type | npm |
| Namespace | @astrojs |
| Name | cloudflare |
| Version | 0.0.0-cf-10-solid-20240329084913 |
| Qualifiers |
|
| Subpath | |
| Is_vulnerable | true |
| Next_non_vulnerable_version | 13.1.10 |
| Latest_non_vulnerable_version | 13.1.10 |
| Affected_by_vulnerabilities |
| 0 |
| url |
VCID-na1j-5218-9fd7 |
| vulnerability_id |
VCID-na1j-5218-9fd7 |
| summary |
Cloudflare has SSRF via redirect following through its image-binding-transform endpoint (incomplete fix for GHSA-qpr4)
## Summary
The `fetch()` call for remote images in `packages/integrations/cloudflare/src/utils/image-binding-transform.ts` (line 28) uses the default `redirect: 'follow'` behavior. This allows the Cloudflare Worker to follow HTTP redirects to arbitrary URLs, bypassing the `isRemoteAllowed()` domain allowlist check which only validates the initial URL.
All three other image fetch paths in the codebase correctly use `{ redirect: 'manual' }`. This is an incomplete fix for GHSA-qpr4-c339-7vq8.
Confirmed on HEAD.
## Root Cause
`image-binding-transform.ts` line 28:
const content = await (isRemotePath(href) ? fetch(imageSrc) : assets.fetch(imageSrc));
Missing `{ redirect: 'manual' }`. The three protected paths:
// image-passthrough-endpoint.ts:23
response = await fetch(href, { redirect: 'manual' });
// assets/endpoint/shared.ts:11
const res = await fetch(src, { redirect: 'manual' });
// assets/utils/remoteProbe.ts:53
const response = await fetch(url, { redirect: 'manual' });
## PoC
Demonstrated with Node.js that `fetch()` without `redirect: 'manual'` follows 302 redirects to arbitrary destinations:
# Server A (allowed domain) returns 302 → Server B (internal)
fetch('http://allowed:19741/img.jpg') → follows 302 → hits http://internal:19742/secret
fetch('http://allowed:19741/img.jpg', {redirect:'manual'}) → returns 302, internal server NOT hit
Attack path: attacker finds an open redirect on an allowed domain, crafts `/_image?href=https://allowed-cdn.com/redirect?url=http://internal-service/`, and the Worker follows the redirect to the unauthorized destination.
## Impact
Bypasses the `image.domains` and `image.remotePatterns` allowlist for the default Cloudflare image service (`cloudflare-binding`). Enables blind SSRF to domains not in the allowlist. Same vulnerability class as GHSA-qpr4-c339-7vq8 (HIGH) which fixed the passthrough endpoint but missed this one.
## Suggested Fix
const content = await (isRemotePath(href) ? fetch(imageSrc, { redirect: 'manual' }) : assets.fetch(imageSrc)); |
| references |
| 0 |
| reference_url |
https://api.first.org/data/v1/epss?cve=CVE-2026-41321 |
| reference_id |
|
| reference_type |
|
| scores |
| 0 |
| value |
0.00047 |
| scoring_system |
epss |
| scoring_elements |
0.14968 |
| published_at |
2026-06-05T12:55:00Z |
|
| 1 |
| value |
0.00047 |
| scoring_system |
epss |
| scoring_elements |
0.14868 |
| published_at |
2026-06-09T12:55:00Z |
|
| 2 |
| value |
0.00047 |
| scoring_system |
epss |
| scoring_elements |
0.14842 |
| published_at |
2026-06-08T12:55:00Z |
|
| 3 |
| value |
0.00047 |
| scoring_system |
epss |
| scoring_elements |
0.14924 |
| published_at |
2026-06-07T12:55:00Z |
|
| 4 |
| value |
0.00047 |
| scoring_system |
epss |
| scoring_elements |
0.14965 |
| published_at |
2026-06-06T12:55:00Z |
|
|
| url |
https://api.first.org/data/v1/epss?cve=CVE-2026-41321 |
|
| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
|
| fixed_packages |
|
| aliases |
CVE-2026-41321, GHSA-88gm-j2wx-58h6
|
| risk_score |
1.4 |
| exploitability |
0.5 |
| weighted_severity |
2.7 |
| resource_url |
http://public2.vulnerablecode.io/vulnerabilities/VCID-na1j-5218-9fd7 |
|
|
| Fixing_vulnerabilities |
|
| Risk_score | 1.4 |
| Resource_url | http://public2.vulnerablecode.io/packages/pkg:npm/%2540astrojs/cloudflare@0.0.0-cf-10-solid-20240329084913 |