Jitterflow

← Blog

SSRF and webhooks: why destination URL validation matters

A webhook destination URL is, from the server's point of view, user-controlled input to an outbound HTTP request. That's the exact shape of a server-side request forgery (SSRF) vulnerability: if nothing stops the URL from pointing at 169.254.169.254 (a cloud provider's instance metadata endpoint), localhost, or an internal service on a private subnet, the webhook platform becomes a proxy an attacker can use to reach infrastructure it was never supposed to touch.

Why this is specifically a webhook-platform problem

Most SSRF writeups are about a single feature — an image-fetching endpoint, a URL preview, a "test this webhook" button. A webhook delivery platform has the same exposure on every single dispatch, indefinitely: a destination URL that was safe when the endpoint was created can later be edited, and every future delivery re-resolves and re-sends to whatever the URL now points at. A one-time check at creation isn't enough.

What validation actually needs to check

A destination URL needs to be rejected if it resolves to a private, loopback, or otherwise disallowed address — and that check needs to run more than once:

This is exactly how Jitterflow validates destinationUrl: on every create, edit, and dispatch, against private and loopback ranges — see Endpoints. A destination that fails this check on create or edit returns 422; if a previously-valid destination is later edited to fail the check between edits, the next ingest call returns 422 too rather than silently attempting delivery.

Tunnel domains are a separate, narrower problem

Local development tunnels (ngrok.io, localtunnel.me, serveo.net, and similar) are public URLs, so they pass a pure private-IP check — but they route straight back to whatever's running on someone's laptop or a temporary dev box, which is a different kind of risk on a shared, multi-tenant platform. Jitterflow's free Developer tier additionally can't point at unverified tunnel domains; paid tiers can, since they've gone through billing verification. A tunnel destination on a restricted tier returns 403, distinct from the 422 a private-IP destination gets.

Full reference

Every endpoint field, its default, and every error code (400, 403, 422) is on Endpoints.

Start free — takes 2 minutes