What It Does
When enabled:- Remote
img,srcset,background,poster, inlinestyle, and<style>asset URLs are rewritten at render time. - The browser loads those assets from your proxy instead of directly from the sender-controlled host.
- The iframe renderer also applies a restrictive CSP so direct remote fetches are blocked even if the rewriter misses a case.
Deploy On Cloudflare Workers
The repo includes a ready-to-deploy Worker in apps/image-proxy.1. Log In To Cloudflare
2. Create a Signing Secret
Use the same secret in both the Worker and the web app:3. Set the Worker Secret
4. Deploy Without Editing Any Repo Files
Replaceimg.example.com with your own hostname:
wrangler.jsonc just to choose a domain.
5. Configure the Inbox Zero App
In your app environment:NEXT_PUBLIC_IMAGE_PROXY_BASE_URLtells the app where to send proxied asset requests.IMAGE_PROXY_SIGNING_SECRETmust match the Worker secret so the proxy can validate signed URLs.
IMAGE_PROXY_SIGNING_SECRET, and configure the proxy validator with a comma-separated list.
Example:
Unsigned Custom Proxy Mode
If you setNEXT_PUBLIC_IMAGE_PROXY_BASE_URL without IMAGE_PROXY_SIGNING_SECRET, Inbox Zero emits unsigned ?u= proxy URLs.
That mode is only for a custom proxy that intentionally accepts unsigned requests. The bundled Cloudflare Worker expects signed URLs when IMAGE_PROXY_SIGNING_SECRET is set.
For production use, signed mode is recommended.
AWS Option
If you do not want Cloudflare, the repo also includes an AWS Lambda adapter in apps/image-proxy-aws. The deployment model is:- deploy the Lambda
- put CloudFront in front of it
- set
NEXT_PUBLIC_IMAGE_PROXY_BASE_URLto your CloudFront URL - use the same
IMAGE_PROXY_SIGNING_SECRET
Self-Hosted Next.js Option
If you are self-hosting and want the simplest setup, Inbox Zero can proxy remote images through its own Next.js app route instead of a separate service. Set these app environment variables:${NEXT_PUBLIC_BASE_URL}/api/image-proxy.
Notes:
- this runs in the main app process, so it is simpler but less isolated than a separate proxy service
- the Next.js route uses the same SSRF protections as the AWS adapter, including DNS resolution and pinned public-address lookups
- keep
IMAGE_PROXY_SIGNING_SECRETset; production rewriting stays disabled without it
Troubleshooting
Health Check
Once deployed, this should return200:
A Specific Image Fails
If an upstream image has redirect issues or unsupported content, the image will fail closed instead of leaking the user’s IP. The Worker logs redirect-chain failures with sanitized URLs that omit query strings, which helps debug upstream redirect loops without logging tracking parameters.The App Still Loads Images Directly
Double-check:NEXT_PUBLIC_IMAGE_PROXY_BASE_URLis set- the browser is rendering email through the normal HTML email viewer
- your proxy hostname is reachable from the browser
Recommended Setup
For most self-hosters:- Deploy the main app normally.
- Choose one proxy mode:
- Simplest: set
NEXT_PUBLIC_IMAGE_PROXY_USE_APP_ROUTE=trueandIMAGE_PROXY_SIGNING_SECRET. - More isolated: deploy the image proxy separately on Cloudflare Workers and set
NEXT_PUBLIC_IMAGE_PROXY_BASE_URLplusIMAGE_PROXY_SIGNING_SECRET.