Documentation
¶
Overview ¶
Package httpclient builds SSRF-safe *http.Client instances for outbound calls to user-configurable destinations (webhook targets, integration callbacks, …). It is dial-time protection: loopback, link-local (incl. the 169.254.169.254 cloud-metadata address), RFC1918/ULA private ranges, and unspecified addresses are refused, with an explicit host/CIDR allowlist as the escape hatch for intentional internal targets.
Protection is resolve-then-verify: the custom DialContext resolves the hostname itself and checks the RESOLVED IPs, never the pre-DNS hostname, so a DNS-rebinding attacker (a name that resolves to a public IP at allowlist-check time but a private IP at connect time) cannot bypass it — there is only one resolution here and it happens immediately before Dial. Because http.Client re-invokes the Transport (and therefore DialContext) for every redirect hop, each hop is independently re-verified for free.
Contract: backlog B2 (docs/implementation/framework-engineering-backlog.md).
Index ¶
Constants ¶
const DefaultTimeout = 10 * time.Second
DefaultTimeout is the client-wide request ceiling applied when Config.Timeout is zero. Callers with a shorter operational SLA (e.g. webhook delivery) pass their own Timeout or further bound the call via the request context.
Variables ¶
var ErrBlockedAddress = errors.New("httpclient: destination address is blocked by SSRF policy")
ErrBlockedAddress is wrapped into every error returned when a dial target (or a resolved address behind a hostname) falls into a blocked address class and is not covered by the allowlist. Callers can check errors.Is(err, ErrBlockedAddress) to distinguish this from ordinary network failures.
Functions ¶
Types ¶
type Config ¶
type Config struct {
// AllowedHosts is the exact-match (case-insensitive), no-wildcard hostname
// allowlist. A request whose URL host is listed here bypasses the
// resolved-IP check entirely for that host (the operator vouches for a
// specific, intentional internal target).
AllowedHosts []string
// AllowedCIDRs is the allowlist for RESOLVED addresses, e.g. "10.20.0.0/16"
// or a single host as "10.20.1.5/32". A resolved IP inside any of these
// networks bypasses the blocked-address-class check.
AllowedCIDRs []string
// Timeout is the client-wide request ceiling. Zero uses DefaultTimeout.
Timeout time.Duration
}
Config controls the SSRF guard and the underlying transport. The zero value is safe and maximally restrictive: no allowlist entries, default timeout — i.e. every private/loopback/link-local/metadata/unspecified address is blocked and only public destinations are reachable.