The SSRF destination classifier (ADR-0005 — enforced at endpoint registration AND again at send time).
A URL is safe when: the scheme is http/https, the host is not a
known cloud-metadata name, and EVERY address the host resolves to is
public. Any private/loopback/link-local/ULA/CGNAT/reserved answer
rejects the URL — one rogue A record among the answers is exactly the
bypass; resolver failure rejects too (fail-closed: an unresolvable
destination cannot be verified safe).
IPv4-mapped and IPv4-compatible IPv6 forms (::ffff:a.b.c.d, ::a.b.c.d)
are normalized to their embedded v4 before classification.
Registration-time resolution is bounded (@resolve_timeout_ms) — an
offline or slow resolver fails the cast loudly rather than hanging it.
Residual (documented, by design of the :httpc adapter): send-time
re-resolution narrows but cannot eliminate the DNS-rebinding TOCTOU
window — full elimination needs connect-time IP pinning the adapter
cannot express.
Summary
Functions
The REGISTRATION-time check: scheme, metadata hostnames, and literal-IP hosts — deterministic and offline-safe (hostname DNS is the delivery runtime's send-time check, per ADR-0005's split).
The VALIDATED ADDRESSES behind a URL — the adapter's pinning input:
{:ok, %{uri: URI, addresses: [ip]}} when every resolved address is
public, {:error, :unsafe | :unresolvable} otherwise. The connection
target comes FROM this same resolution, which is what closes the
rebinding TOCTOU (validate-then-connect-on-the-same-answer).
True when url is an http(s) URL whose host is not metadata and whose
resolved addresses are all public.
Functions
The REGISTRATION-time check: scheme, metadata hostnames, and literal-IP hosts — deterministic and offline-safe (hostname DNS is the delivery runtime's send-time check, per ADR-0005's split).
@spec resolve_public(term()) :: {:ok, %{uri: URI.t(), addresses: [:inet.ip_address()]}} | {:error, atom()}
The VALIDATED ADDRESSES behind a URL — the adapter's pinning input:
{:ok, %{uri: URI, addresses: [ip]}} when every resolved address is
public, {:error, :unsafe | :unresolvable} otherwise. The connection
target comes FROM this same resolution, which is what closes the
rebinding TOCTOU (validate-then-connect-on-the-same-answer).
True when url is an http(s) URL whose host is not metadata and whose
resolved addresses are all public.