#2915·inbox-zero

feat: add WEBHOOK_ALLOWED_HOSTS env var to bypass SSRF checks for self-hosted local webhooks

Author: j3k0Created Jun 25, 2026Updated Jun 26, 2026

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 (no http:)
  • 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):

  1. utils/webhook-validation.tsvalidateWebhookUrl / validateWebhookUrlFormat
  2. utils/network/safe-http-url.tsisSafeExternalHttpUrl / resolveSafeExternalHttpUrl

If the parsed hostname is in the allowlist, skip DNS resolution and private-IP checks.

Example

env
WEBHOOK_ALLOWED_HOSTS=my-local-service.internal

Security

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.