Documentation
¶
Overview ¶
Package ssrf is the canonical SSRF-defense layer (S35). The S33 webhook deliverer was the first caller; future outbound-fetch paths (avatar mirroring, OG-image scraping, OAuth metadata fetches, etc.) plug into the same Config + HTTPClient.
The pattern, copied from the webhook package and codified here:
- Resolve the hostname.
- Reject the request if ANY resolved IP falls in a private, loopback, link-local, CGNAT, multicast, or ULA range.
- Dial the resolved IP directly so a re-resolve at connect time can't rebind to a private address (DNS rebinding).
- Reject schemes other than http/https and ports outside the operator's allow-list (default 80/443/8080/8443).
Operators with a self-hosted CI behind a private IP set AllowedHosts (exact-match, case-insensitive) which implicitly allows the host to bypass the IP block-list. Don't confuse with AllowPrivateNetworks (global bypass — for testing only).
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func IsForbiddenIP ¶
IsForbiddenIP reports whether the IP belongs to any of the ranges the spec marks as off-limits. Exposed so callers running their own validation (e.g. a config-time URL probe) can reuse the check.
Types ¶
type Config ¶
type Config struct {
AllowedSchemes []string
AllowedPorts []int
AllowPrivateNetworks bool
AllowedHosts []string
DialTimeout time.Duration
RequestTimeout time.Duration
Resolver *net.Resolver
}
Config tunes the defense. Defaults are safe for a single-tenant public deployment; self-hosters extend AllowedHosts / AllowedPorts.
func (Config) HTTPClient ¶
HTTPClient returns a redirect-following-disabled client whose dialer enforces the SSRF rules. 3xx is treated as success-like (no-follow) since following is itself an SSRF amplifier.