Documentation
¶
Overview ¶
Package urlguard is the canonical SSRF guard for every outbound fetch abcd makes.
abcd fetches URLs from two places — memory ingest takes one from the operator, and the citation refresh takes them from committed documentation — and in both the address is attacker-influenceable content. A guard that lives inside one caller is a guard the next caller reimplements slightly differently, which is exactly how a metadata endpoint ends up reachable from the second fetch path. So the predicate, the name check, and the connect-time re-check live here once, and every fetcher composes them.
The address predicate is a PARAMETER of the name check and the dial control rather than a hard-wired call, for one reason: a fetch path can then be exercised against an httptest server (which binds loopback) by relaxing the predicate in the test alone, while the shipped default — BlockedIP — is never relaxed anywhere. A guard nobody can test end-to-end is a guard nobody trusts.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func BlockedIP ¶
BlockedIP reports whether ip is in a range that must never be fetched: loopback (127/8, ::1), link-local (169.254/16, fe80::/10 unicast and multicast), private (10/8, 172.16/12, 192.168/16, fc00::/7 via net.IP.IsPrivate), the unspecified address, any multicast address, the reserved non-private IPv4 ranges above — notably CGNAT 100.64/10 — and the fixed provider platform magic IPs in public space (platformMagicV4). This is what keeps cloud metadata endpoints (e.g. 169.254.169.254, 168.63.129.16) and abcd-lint:allow internal services out of reach.
func CheckHost ¶
CheckHost refuses a host that is an internal/metadata name or that resolves to a blocked address, under the shipped default policy.
func CheckHostWith ¶
CheckHostWith is CheckHost with the address predicate supplied by the caller. It runs before the initial request and on every redirect hop. An IP literal is checked directly (no DNS); a name is rejected outright when it is an *.internal / metadata name, otherwise every resolved address is checked.
The NAME half is policy-independent: an *.internal or metadata name never gets as far as an address, so no predicate can wave it through.
func DialControl ¶
DialControl builds a net.Dialer Control hook that re-checks the ACTUAL resolved IP of every dialled connection, closing the DNS-rebinding gap between a name-based guard and the transport's own resolution.
Types ¶
This section is empty.