security: add remotePatterns validation to /cdn-cgi/image/ handler - #1330
security: add remotePatterns validation to /cdn-cgi/image/ handler#1330Ashutosh0x wants to merge 1 commit into
Conversation
🦋 Changeset detectedLatest commit: 9d417ed The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
| if (!hasRemoteMatch(__IMAGES_REMOTE_PATTERNS__, parsedUrl)) { | ||
| return new Response('"url" parameter is not allowed', { status: 400 }); | ||
| } |
There was a problem hiding this comment.
🟡 Remote images stop working in local development for apps using the Cloudflare image loader
Remote image URLs served through the development image handler are now rejected (hasRemoteMatch(...) at packages/cloudflare/src/cli/templates/images.ts:216) unless they are listed in the app's remote image allow-list, so images that load fine in production show as broken during development.
Impact: Developers using the Cloudflare image loader without configuring an allow-list see 400 errors and broken remote images locally, while the same pages work once deployed.
Why dev/prod parity is broken by the new allow-list check
/cdn-cgi/image/... requests never reach the worker in production (packages/cloudflare/src/cli/templates/worker.ts:27-30); Cloudflare's edge fetches the origin image with no remotePatterns check. The handler exists specifically to emulate that edge behavior in dev (changelog entry "make dev /cdn-cgi/image behaves like prod for consistency").
When a custom image loader (e.g. the Cloudflare loader) is used, Next.js does not require images.remotePatterns to be configured, so __IMAGES_REMOTE_PATTERNS__ (populated from the images manifest in packages/cloudflare/src/cli/build/open-next/compile-images.ts:21) is frequently []. With an empty list hasRemoteMatch always returns false (packages/cloudflare/src/cli/templates/images.ts:727-735), so every absolute-URL image request returns "url" parameter is not allowed in dev while working in prod.
If the goal is defense-in-depth for service-binding calls, consider only rejecting when patterns are configured, or gating the check so it does not regress the dev emulation path.
Was this helpful? React with 👍 or 👎 to provide feedback.
| "@opennextjs/cloudflare": patch | ||
| --- | ||
|
|
||
| security: add remotePatterns validation to /cdn-cgi/image/ handler |
There was a problem hiding this comment.
🟡 Changeset uses a change type that is not allowed by the contribution rules
The new changeset entry starts with security: (.changeset/fix-cdn-cgi-image-ssrf.md:5), but the repository requires one of feature | fix | refactor | docs | chore, so the generated changelog will not follow the project's documented format.
Impact: The released changelog entry is inconsistent with every other entry in the project.
Rule reference
AGENTS.md ("Changesets") and CONTRIBUTING.md ("Changeset message format") both state the TYPE must be one of feature, fix, refactor, docs or chore.
| security: add remotePatterns validation to /cdn-cgi/image/ handler | |
| fix: add remotePatterns validation to /cdn-cgi/image/ handler |
Was this helpful? React with 👍 or 👎 to provide feedback.
a4fc348 to
9d417ed
Compare
Summary
The handleCdnCgiImageRequest() handler in images.ts performs etch(parseResult.url) with zero URL validation, unlike handleImageRequest() which validates URLs via hasRemoteMatch() against
emotePatterns.
This was the root cause of CVE-2026-3125. The original patch blocked the backslash path normalization bypass at the edge, but did NOT add code-level validation to the handler.
The Problem
handleCdnCgiImageRequest() is documented as development-only (worker.ts L27-28), but:
The Fix
This patch adds
emotePatterns validation to handleCdnCgiImageRequest(), matching the validation already performed by handleImageRequest() via hasRemoteMatch(). Remote URLs that don't match the configured patterns are rejected with a 400 response.
Related