Documentation
¶
Overview ¶
Package safehttp is an SSRF-resistant wrapper around Go's net/http for outbound requests to URLs provided by users or external systems.
Use it when a service fetches URLs from users, webhooks, OAuth metadata, imported documents, third-party API payloads, or any other source it does not fully control. safehttp keeps those requests constrained to allowed destinations and blocks loopback, private networks, cloud metadata, and other internal or special-use addresses.
NewClient starts with a public-HTTPS-only configuration. Requests must use HTTPS, target a public destination, and use port 443. URL credentials, custom Request.Host values, proxies, other schemes or ports, and private or special-use IP ranges are blocked. Redirects are followed by default, but every redirect target is revalidated.
NewGuard exposes URL and request validation without constructing an http.Client. Use guard-only checks for preflight validation; use NewClient or NewTransport for the outbound HTTP path.
Index ¶
- Variables
- func NewClient(opts ...Option) (*http.Client, error)
- func NewTransport(base *http.Transport, opts ...Option) (http.RoundTripper, error)
- type BlockError
- type Guard
- func (g *Guard) CheckAddr(network string, addr netip.AddrPort) error
- func (g *Guard) CheckRedirect(req *http.Request, via []*http.Request) error
- func (g *Guard) CheckRequest(req *http.Request) error
- func (g *Guard) CheckURL(u *url.URL) error
- func (g *Guard) ControlContext(_ context.Context, network, address string, _ syscall.RawConn) error
- type Option
- func AllowCIDRs(cidrs ...string) Option
- func AllowCredentials() Option
- func AllowCustomHostHeader() Option
- func AllowHosts(hosts ...string) Option
- func AllowMethods(methods ...string) Option
- func AllowPorts(ports ...uint16) Option
- func AllowPrefixes(prefixes ...netip.Prefix) Option
- func AllowSchemes(schemes ...string) Option
- func ClientTimeout(timeout time.Duration) Option
- func DenyCIDRs(cidrs ...string) Option
- func DenyPrefixes(prefixes ...netip.Prefix) Option
- func Dialer(dialer *net.Dialer) Option
- func MaxRedirects(n int) Option
- func MaxResponseBytes(n int64) Option
- func MaxResponseHeaderBytes(n int64) Option
- func NoRedirects() Option
Constants ¶
This section is empty.
Variables ¶
var ( ErrBlocked = errors.New("safehttp: blocked request") ErrInvalidURL = errors.New("safehttp: invalid url") ErrBlockedScheme = errors.New("safehttp: blocked scheme") ErrBlockedHost = errors.New("safehttp: blocked host") ErrBlockedPort = errors.New("safehttp: blocked port") ErrBlockedMethod = errors.New("safehttp: blocked method") ErrBlockedAddress = errors.New("safehttp: blocked address") ErrBlockedNetwork = errors.New("safehttp: blocked network") ErrBlockedRedirect = errors.New("safehttp: blocked redirect") ErrBlockedCredentials = errors.New("safehttp: blocked credentials") ErrBlockedHostHeader = errors.New("safehttp: blocked host header") ErrBlockedTransport = errors.New("safehttp: blocked transport") )
Functions ¶
func NewTransport ¶
NewTransport clones base, installs guarded dialing, and returns a safe round tripper.
Types ¶
type BlockError ¶
type BlockError struct {
// Reason is a short human-readable explanation of the decision.
Reason string
// URL is redacted before storage. It never includes URL credentials,
// query strings, or fragments.
URL string
// Scheme, Host, Port, Method, and Addr identify the checked input when they
// are known. Some errors only have one or two of these fields populated.
Scheme string
Host string
Port uint16
Method string
Addr netip.AddrPort
// Rule is diagnostic detail for the matched policy rule, such as a denied
// prefix, "private", "loopback", or a blocked network name. Use errors.Is
// with the ErrBlocked* sentinels for stable control flow.
Rule string
// contains filtered or unexported fields
}
BlockError describes a request, redirect, address, or response blocked by safehttp.
func (*BlockError) Error ¶
func (e *BlockError) Error() string
func (*BlockError) Is ¶
func (e *BlockError) Is(target error) bool
func (*BlockError) Unwrap ¶
func (e *BlockError) Unwrap() error
type Guard ¶
type Guard struct {
// contains filtered or unexported fields
}
Guard validates outbound HTTP requests, redirects, and dialed addresses.
func (*Guard) CheckAddr ¶
CheckAddr validates the concrete network address selected for dialing.
This is the security boundary that matters after DNS resolution. A URL host like example.com may be syntactically fine, but the resolver can still return 127.0.0.1, 169.254.169.254, an RFC1918 address, or another special range. CheckAddr is used for both IP literal URLs and net.Dialer.ControlContext.
func (*Guard) CheckRedirect ¶
CheckRedirect validates a redirect target for http.Client.CheckRedirect.
func (*Guard) CheckRequest ¶
CheckRequest validates an HTTP request before it is sent.
func (*Guard) CheckURL ¶
CheckURL validates a URL before it is used for an outbound request.
This check works only from the parsed url.URL fields; callers should parse raw strings before handing them to safehttp. DNS names are intentionally not resolved here. Resolution happens inside the transport, and the resulting address is checked later by CheckAddr through net.Dialer.ControlContext.
type Option ¶
type Option func(*options) error
Option changes safehttp construction.
func AllowCIDRs ¶
AllowCIDRs parses and permits destination CIDR ranges.
This is the string form of AllowPrefixes for callers that load policy from text or environment-specific configuration.
func AllowCustomHostHeader ¶
func AllowCustomHostHeader() Option
AllowCustomHostHeader permits a Request.Host value that differs from the URL.
func AllowHosts ¶
AllowHosts restricts requests to exact hosts or leading wildcard patterns.
func AllowMethods ¶
AllowMethods restricts requests to the provided HTTP methods.
func AllowPorts ¶
AllowPorts replaces the default allowed destination ports.
func AllowPrefixes ¶
AllowPrefixes permits destination IP prefixes that the default policy blocks.
Use it for tests, private infrastructure, or other non-public destinations. DenyPrefixes still wins when the same address is covered by both an allow rule and a deny rule.
func AllowSchemes ¶
AllowSchemes replaces the default allowed URL schemes.
func ClientTimeout ¶
ClientTimeout sets http.Client.Timeout on clients built by NewClient.
func DenyCIDRs ¶
DenyCIDRs parses and blocks additional destination CIDR ranges.
This is the string form of DenyPrefixes for callers that load policy from text or environment-specific configuration.
func DenyPrefixes ¶
DenyPrefixes blocks additional destination IP prefixes.
Deny rules are checked before allow rules. Use them to make the default public-destination policy stricter for an application.
func Dialer ¶
Dialer uses a copy of dialer and installs safehttp's control hook on the copy.
Existing Control or ControlContext hooks are rejected because replacing them is how safehttp enforces the post-DNS address policy.
func MaxRedirects ¶
MaxRedirects sets how many redirects a client may follow.
func MaxResponseBytes ¶
MaxResponseBytes caps the number of response body bytes a caller may read.
The limit is enforced while the caller reads the response body. safehttp does not buffer the body up front.
func MaxResponseHeaderBytes ¶
MaxResponseHeaderBytes sets http.Transport.MaxResponseHeaderBytes.