# `AshHooks.Ssrf`
[🔗](https://github.com/baselabs/ash_hooks/blob/v2.0.3/lib/ash_hooks/ssrf.ex#L1)

Destination validation for outbound webhooks.

Endpoint registration uses `registration_safe?/1`: it checks the HTTP(S)
scheme, known metadata hostnames, and literal IP addresses without DNS.
Hostname resolution happens at send time, so registration does not depend
on the destination's current DNS availability.

`safe_url?/1` and `resolve_public/2` resolve IPv4 and IPv6 addresses and
require a nonempty result containing only public addresses. Private,
loopback, link-local, unique-local, shared, and reserved ranges are rejected.
IPv4-mapped and IPv4-compatible IPv6 addresses are classified using their
embedded IPv4 address.

DNS resolution has a two-second ceiling, shortened by a supplied operation
deadline. Both supplied HTTP adapters connect to an address from the
validated result while retaining the original hostname for TLS and HTTP.

# `registration_safe?`

```elixir
@spec registration_safe?(term()) :: boolean()
```

Checks the scheme, metadata hostnames, and literal IP addresses at
registration. This check does not resolve hostnames.

# `resolve_public`

Returns validated addresses behind a URL for connection pinning:
`{:ok, %{uri: URI, addresses: [ip]}}` when every resolved address is
public, `{:error, :unsafe | :unresolvable}` otherwise. The connection
target must come from this same result to prevent DNS rebinding between
validation and connection.

# `safe_url?`

```elixir
@spec safe_url?(term()) :: boolean()
```

True when `url` is an http(s) URL whose host is not metadata and whose
resolved addresses are all public.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
