feat: add WEBHOOK_ALLOWED_HOSTS env var to bypass SSRF checks for self-hosted local webhooks
Problem
The CALL_WEBHOOK rule action is unusable for self-hosted users who want to send webhook payloads to services on the same machine or local network. The SSRF protection is hard-coded with no configuration bypass:
localhost,127.0.0.1, and all private IP ranges are blocked- In production, only
https:is allowed (nohttp:) - Any hostname resolving to a private IP is rejected
Use case
A self-hosted Inbox Zero instance wants to POST email data to a local service on the same machine (or local network). The local service is reachable via a hostname that resolves to a CGNAT/VPN address. The user already has or can set up HTTPS (self-signed). But the DNS resolution check catches the private IP and rejects it with no recourse.
Suggested solution
Add an optional WEBHOOK_ALLOWED_HOSTS env var — a comma-separated list of hostnames that bypass the hostname-blocklist and private-IP checks. The scheme restriction (http: vs https:) and other format validation would still apply.
The check would be added in two places (same pattern in both):
utils/webhook-validation.ts—validateWebhookUrl/validateWebhookUrlFormatutils/network/safe-http-url.ts—isSafeExternalHttpUrl/resolveSafeExternalHttpUrl
If the parsed hostname is in the allowlist, skip DNS resolution and private-IP checks.
Example
WEBHOOK_ALLOWED_HOSTS=my-local-service.internalSecurity
This is a self-hosted-only feature. Users opting into it accept the SSRF risk for those specific hosts. No change to the default (secure) behavior for anyone who doesn't set the variable.
Source: elie222/inbox-zero