[GH-ISSUE #1065] next/image: improve error message and support images.dangerouslyAllowLocalIP for private-IP rejections #232

Open
opened 2026-05-06 12:38:24 +02:00 by BreizhHardware · 0 comments

Originally created by @github-actions[bot] on GitHub (May 5, 2026).
Original GitHub issue: https://github.com/cloudflare/vinext/issues/1065

Upstream change

Next.js commit 5452439f3db2a78967178ca4180b27fb48393a19 (PR #91686) updates the SSRF guard in fetchExternalImage to:

  1. Log a clearer error when an upstream image hostname resolves to a private IP, including a hint about images.dangerouslyAllowLocalIP.
  2. Document that dangerouslyAllowLocalIP may be needed when hosting in a VPC with split-horizon DNS, while warning about the SSRF risk.

Relevant change in packages/next/src/server/image-optimizer.ts:

   Log.error(
     'upstream image',
     href,
-    'resolved to private ip',
-    JSON.stringify(privateIps)
+    'hostname resolved to private IP',
+    JSON.stringify(privateIps),
+    'If this is expected and you understand SSRF risk, use images.dangerouslyAllowLocalIP = true to continue.'
   )
   throw new ImageError(400, '"url" parameter is not allowed')

A new unit test (test/unit/image-optimizer/fetch-external-image.test.ts) confirms:

  • Private IP hostnames are rejected with 400 and a generic "url" parameter is not allowed message.
  • dangerouslyAllowLocalIP: true allows the fetch to proceed.

Why this matters for vinext

vinext does not currently ship a full Next.js-compatible image optimizer (image handling on Cloudflare typically defers to Cloudflare Images / the platform). However, to the extent that vinext provides any next/image runtime or honors images.* config:

  • The SSRF guard for upstream image fetches should be in place for parity.
  • The images.dangerouslyAllowLocalIP config option (and its behavior) should be supported or explicitly documented as not applicable.
  • Error messages emitted on rejection should match Next.js for ecosystem compatibility.

This is a low-priority parity item — most Cloudflare deployments will rely on the platform's image pipeline rather than vinext's own optimizer.

Action items

  • Confirm vinext's current next/image story (built-in optimizer vs. delegate to platform).
  • If vinext fetches external images at runtime, port the private-IP guard and the images.dangerouslyAllowLocalIP opt-out.
  • Match the updated error/log message for ecosystem parity.
  • Document the behavior in vinext docs (especially for VPC / split-horizon DNS scenarios).

References

Originally created by @github-actions[bot] on GitHub (May 5, 2026). Original GitHub issue: https://github.com/cloudflare/vinext/issues/1065 ## Upstream change Next.js commit [5452439f3db2a78967178ca4180b27fb48393a19](https://github.com/vercel/next.js/commit/5452439f3db2a78967178ca4180b27fb48393a19) (PR [#91686](https://github.com/vercel/next.js/pull/91686)) updates the SSRF guard in `fetchExternalImage` to: 1. Log a clearer error when an upstream image hostname resolves to a private IP, including a hint about `images.dangerouslyAllowLocalIP`. 2. Document that `dangerouslyAllowLocalIP` may be needed when hosting in a VPC with split-horizon DNS, while warning about the SSRF risk. Relevant change in `packages/next/src/server/image-optimizer.ts`: ```diff Log.error( 'upstream image', href, - 'resolved to private ip', - JSON.stringify(privateIps) + 'hostname resolved to private IP', + JSON.stringify(privateIps), + 'If this is expected and you understand SSRF risk, use images.dangerouslyAllowLocalIP = true to continue.' ) throw new ImageError(400, '"url" parameter is not allowed') ``` A new unit test (`test/unit/image-optimizer/fetch-external-image.test.ts`) confirms: - Private IP hostnames are rejected with `400` and a generic `"url" parameter is not allowed` message. - `dangerouslyAllowLocalIP: true` allows the fetch to proceed. ## Why this matters for vinext vinext does not currently ship a full Next.js-compatible image optimizer (image handling on Cloudflare typically defers to Cloudflare Images / the platform). However, to the extent that vinext provides any next/image runtime or honors `images.*` config: - The SSRF guard for upstream image fetches should be in place for parity. - The `images.dangerouslyAllowLocalIP` config option (and its behavior) should be supported or explicitly documented as not applicable. - Error messages emitted on rejection should match Next.js for ecosystem compatibility. This is a low-priority parity item — most Cloudflare deployments will rely on the platform's image pipeline rather than vinext's own optimizer. ## Action items - [ ] Confirm vinext's current next/image story (built-in optimizer vs. delegate to platform). - [ ] If vinext fetches external images at runtime, port the private-IP guard and the `images.dangerouslyAllowLocalIP` opt-out. - [ ] Match the updated error/log message for ecosystem parity. - [ ] Document the behavior in vinext docs (especially for VPC / split-horizon DNS scenarios). ## References - Commit: https://github.com/vercel/next.js/commit/5452439f3db2a78967178ca4180b27fb48393a19 - PR: https://github.com/vercel/next.js/pull/91686
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/vinext#232
No description provided.