Documentation
¶
Overview ¶
Package safehttp builds an http.Client suitable for fetching from untrusted hosts. The transport applies three defences in concert:
Dial-time IP gate. DNS is resolved once per dial; each resolved address is checked against the block list (loopback, RFC1918, CGNAT 100.64.0.0/10, link-local, multicast, unspecified) before any TCP connect. The connection then dials the resolved IP directly, so a rebind between check and connect cannot escape the gate.
Redirect cap. Go's default ignores chain length and re-trusts each hop. CheckRedirect caps at 10 and re-validates every redirect target.
Scheme gate on redirect. file://, gopher://, ftp://, data:// are rejected — the only reason a registry would 30x to those is to exfiltrate something.
Threat model: a compromised registry, CDN, or maliciously-crafted URL that returns a 30x to http://localhost or an RFC1918 address should not be able to use this transport to probe internal services or exfiltrate local files. The gate is on every dial including redirect targets.
Index ¶
Constants ¶
const (
// MaxRedirects bounds the redirect chain length.
MaxRedirects = 10
)
Variables ¶
This section is empty.
Functions ¶
func CheckHostIP ¶
CheckHostIP reports whether an IP is acceptable for the named host under the supplied options. It applies AllowPrivateHosts in addition to the checks performed by CheckIP. Use NewHostIPChecker when checking multiple addresses with the same options.
func CheckIP ¶
CheckIP reports whether an IP is acceptable to dial under the supplied options. Exported so other transports (e.g. registries/ fetch, which manages its own DialContext for DNS caching) can apply the same gate without wiring through a full safehttp client.
func EnableLoopbackForTesting ¶
func EnableLoopbackForTesting()
EnableLoopbackForTesting flips the SSRF dial gate's loopback and private-IP checks off for the calling test binary. Use in TestMain; never call from production code.
Types ¶
type HostIPChecker ¶
type HostIPChecker struct {
// contains filtered or unexported fields
}
HostIPChecker checks resolved IP addresses against a normalized host allowlist. It can be reused across dials without rebuilding the allowlist.
func NewHostIPChecker ¶
func NewHostIPChecker(opts Options) *HostIPChecker
NewHostIPChecker creates a reusable checker from opts.
type Options ¶
type Options struct {
// AllowLoopback disables the loopback (127.0.0.0/8, ::1) check.
// Only set for tests or explicit operator allowlists.
AllowLoopback bool
// AllowPrivate disables the RFC1918 / ULA / CGNAT checks.
// Only set for tests or explicit operator allowlists.
AllowPrivate bool
// AllowPrivateHosts permits named hosts and IP literals to resolve or
// connect to RFC1918, ULA, or CGNAT addresses. Loopback and link-local
// addresses remain blocked. Host matching is case-insensitive and ignores
// ports and trailing dots.
AllowPrivateHosts []string
}
Options configures a safehttp client. The zero value gives the production-strict gate; tests and explicit operator allowlists can opt parts of it off.