ssrf

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 10, 2026 License: AGPL-3.0 Imports: 8 Imported by: 0

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:

  1. Resolve the hostname.
  2. Reject the request if ANY resolved IP falls in a private, loopback, link-local, CGNAT, multicast, or ULA range.
  3. Dial the resolved IP directly so a re-resolve at connect time can't rebind to a private address (DNS rebinding).
  4. 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 Is

func Is(err error) bool

Is reports whether err is or wraps an *Error.

func IsForbiddenIP

func IsForbiddenIP(ip net.IP) bool

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 Default

func Default() Config

Default returns the production defaults.

func (Config) HTTPClient

func (c Config) HTTPClient() *http.Client

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.

func (Config) Validate

func (c Config) Validate(rawURL string) error

Validate runs the syntactic gate (scheme, port, host shape) without resolving DNS. dialContext re-runs the IP-level checks at connect time so a passing Validate doesn't imply the URL is safe to dial — it's the early-rejection cheap gate.

type Error

type Error struct {
	URL    string
	Reason string
}

Error wraps a rejection so callers can `errors.As` to the typed shape and surface the specific reason in admin logs / UI.

func (*Error) Error

func (e *Error) Error() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL