Documentation
¶
Overview ¶
Package ssrf is the SSRF (server-side request forgery) guard: the private/internal CIDR table, host resolution checks with a short-TTL DNS cache, and the connect-time dialer control that closes the DNS-rebinding TOCTOU window. Extracted from package main (proxy.go + security.go) per ADR-0002 so outbound-fetching leaves (blocklist feeds, threat feeds) can move without importing main. package main keeps thin wrappers (isPrivateIP / isPrivateHost / the swappable ssrfSafeDialContext var) so every existing call site — and the CodeQL inline-guard convention at those sites — is unchanged.
Index ¶
- func AllowLoopbackForTest() (restore func())
- func CacheCleanup()
- func CacheDelete(host string)
- func CacheReset()
- func CacheStore(host string, private bool)
- func Control(network, address string, _ syscall.RawConn) error
- func PrivateHost(hostport string) error
- func PrivateIP(ip net.IP) bool
- func SafeDialContext(ctx context.Context, network, addr string) (net.Conn, error)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AllowLoopbackForTest ¶
func AllowLoopbackForTest() (restore func())
AllowLoopbackForTest removes the loopback ranges from the guard's CIDR table and returns a restore func. Test support for E2E fixtures that must CONNECT/dial to 127.0.0.1 through the real proxy path — never call from production code. The DNS verdict cache is reset on both swap and restore.
func CacheCleanup ¶
func CacheCleanup()
CacheCleanup evicts expired entries (called periodically from the main tick loop, connlimit_startup.go).
func CacheDelete ¶
func CacheDelete(host string)
CacheDelete removes a host's cached verdict (test support).
func CacheReset ¶
func CacheReset()
CacheReset replaces the DNS verdict cache with an empty one (test support; pairs with AllowLoopbackForTest so stale verdicts don't leak across the guard-table swap).
func CacheStore ¶
CacheStore seeds a DNS verdict directly. Test support: lets tests mark loopback hosts public so local httptest servers pass the guard; pair with CacheDelete in cleanup.
func Control ¶
Control rejects a connection when the resolved peer address falls into any private/internal range. Installed as net.Dialer.Control, it runs AFTER DNS resolution and IMMEDIATELY BEFORE connect(2), closing the TOCTOU window that a pre-flight LookupHost leaves open (DNS-rebinding: public IP on the pre-check, private IP on the real dial).
address is the resolved IP:port that the kernel is about to connect to (never a hostname at this layer), so net.ParseIP always succeeds for a well-formed stack. We still fail-closed on any parse anomaly.
func PrivateHost ¶
PrivateHost resolves host (host or host:port) and returns an error if any resolved IP falls within a private/internal range. This prevents SSRF via proxy CONNECT to loopback, RFC 1918, link-local, or metadata endpoints. Results are cached in the package DNS cache (30s TTL) to avoid redundant DNS lookups.
func SafeDialContext ¶
SafeDialContext is a net.Dialer.DialContext replacement that rejects connections to private/internal IPs. Use as the DialContext in an http.Transport to prevent SSRF at the network level, independent of URL validation. Safe against DNS rebinding because the check runs on the post-resolution address that will actually be connected.
Types ¶
This section is empty.