fix(06-13): full IANA special-use SSRF tables and reject zoned dial targets

This commit is contained in:
Jakub Zych
2026-09-21 19:44:51 +02:00
parent 4bad1a43a2
commit b1079ab8a4
4 changed files with 47 additions and 18 deletions

View File

@@ -2,24 +2,28 @@ package fetchguard
import "net/netip"
// privateV4 is a literal port of ManualCoverUrlFetcher.php PRIVATE_V4_CIDRS.
var privateV4 = []netip.Prefix{
netip.MustParsePrefix("127.0.0.0/8"),
netip.MustParsePrefix("10.0.0.0/8"),
netip.MustParsePrefix("172.16.0.0/12"),
netip.MustParsePrefix("192.168.0.0/16"),
netip.MustParsePrefix("169.254.0.0/16"),
netip.MustParsePrefix("100.64.0.0/10"),
netip.MustParsePrefix("0.0.0.0/8"),
}
// privateV4 is the IANA IPv4 special-purpose non-public set. It is a strict
// superset of ManualCoverUrlFetcher.php's lists (06-VERIFICATION gap 3).
var privateV4 = mustPrefixes(
"0.0.0.0/8", "10.0.0.0/8", "100.64.0.0/10", "127.0.0.0/8",
"169.254.0.0/16", "172.16.0.0/12", "192.0.0.0/24", "192.0.2.0/24",
"192.88.99.0/24", "192.168.0.0/16", "198.18.0.0/15", "198.51.100.0/24",
"203.0.113.0/24", "224.0.0.0/4", "240.0.0.0/4",
)
// privateV6 is a literal port of PRIVATE_V6_PREFIXES. PHP lists bare "::1"
// as a prefix-less loopback literal; it is expressed here as ::1/128 so
// Prefix.Contains works uniformly with the CIDR entries.
var privateV6 = []netip.Prefix{
netip.MustParsePrefix("::1/128"),
netip.MustParsePrefix("fe80::/10"),
netip.MustParsePrefix("fc00::/7"),
// privateV6 is the IANA IPv6 special-purpose non-public set. 2002::/16 and
// 64:ff9b::/96 are handled by embeddedTransitionIPv4 instead.
var privateV6 = mustPrefixes(
"::/96", "100::/64", "2001::/23", "2001:db8::/32", "3fff::/20",
"5f00::/16", "fc00::/7", "fe80::/10", "fec0::/10", "ff00::/8",
)
func mustPrefixes(cidrs ...string) []netip.Prefix {
out := make([]netip.Prefix, len(cidrs))
for i, c := range cidrs {
out[i] = netip.MustParsePrefix(c)
}
return out
}
var (
@@ -35,7 +39,7 @@ func isReservedOrPrivate(addr netip.Addr) bool {
if !addr.IsValid() {
return true
}
addr = addr.Unmap()
addr = addr.WithZone("").Unmap()
if addr.IsMulticast() || addr.IsUnspecified() {
return true
}