Upstream change
Next.js commit 5452439f3db2a78967178ca4180b27fb48393a19 (PR #91686) updates the SSRF guard in fetchExternalImage to:
- Log a clearer error when an upstream image hostname resolves to a private IP, including a hint about
images.dangerouslyAllowLocalIP.
- 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
References
Upstream change
Next.js commit 5452439f3db2a78967178ca4180b27fb48393a19 (PR #91686) updates the SSRF guard in
fetchExternalImageto:images.dangerouslyAllowLocalIP.dangerouslyAllowLocalIPmay 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:400and a generic"url" parameter is not allowedmessage.dangerouslyAllowLocalIP: trueallows 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:images.dangerouslyAllowLocalIPconfig option (and its behavior) should be supported or explicitly documented as not applicable.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
images.dangerouslyAllowLocalIPopt-out.References