Commit 0babae2db0
Verified · cmc
Layout: unified · split
internal/webhook/webhook.go +8 −4
| @@ -48,9 +48,9 @@ func ValidateURL(raw string, allowLocal bool) error { | ||
| 48 | 48 | } |
| 49 | 49 | |
| 50 | 50 | // CheckAddrs refuses host when any of its resolved addresses is |
| 51 | // loopback, private or link-local, unless allowLocal. A caller resolves | |
| 52 | // immediately before connecting and connects only to the addresses it | |
| 53 | // checked. | |
| 51 | // loopback, private, shared (100.64.0.0/10), link-local, multicast or | |
| 52 | // unspecified, unless allowLocal. A caller resolves immediately before | |
| 53 | // connecting and connects only to the addresses it checked. | |
| 54 | 54 | func CheckAddrs(host string, ips []net.IP, allowLocal bool) error { |
| 55 | 55 | if allowLocal { |
| 56 | 56 | return nil |
| @@ -63,9 +63,13 @@ func CheckAddrs(host string, ips []net.IP, allowLocal bool) error { | ||
| 63 | 63 | return nil |
| 64 | 64 | } |
| 65 | 65 | |
| 66 | // cgnat is the shared address space of RFC 6598, which carriers and | |
| 67 | // overlay networks such as Tailscale use as private space. | |
| 68 | var cgnat = &net.IPNet{IP: net.IPv4(100, 64, 0, 0), Mask: net.CIDRMask(10, 32)} | |
| 69 | ||
| 66 | 70 | func isForbidden(ip net.IP) bool { |
| 67 | 71 | return ip.IsLoopback() || ip.IsPrivate() || ip.IsLinkLocalUnicast() || |
| 68 | ip.IsLinkLocalMulticast() || ip.IsUnspecified() | |
| 72 | ip.IsMulticast() || ip.IsUnspecified() || cgnat.Contains(ip) | |
| 69 | 73 | } |
| 70 | 74 | |
| 71 | 75 | type Deliverer struct { |
internal/webhook/webhook_test.go +13
| @@ -19,3 +19,16 @@ func TestCheckAddrs(t *testing.T) { | ||
| 19 | 19 | t.Fatalf("allow_local: %v", err) |
| 20 | 20 | } |
| 21 | 21 | } |
| 22 | ||
| 23 | func TestIsForbiddenCGNATAndMulticast(t *testing.T) { | |
| 24 | for _, s := range []string{"100.64.0.1", "100.127.255.254", "224.0.0.251", "239.1.2.3", "ff02::1", "ff0e::1"} { | |
| 25 | if !isForbidden(net.ParseIP(s)) { | |
| 26 | t.Errorf("%s allowed", s) | |
| 27 | } | |
| 28 | } | |
| 29 | for _, s := range []string{"100.63.255.255", "100.128.0.1", "203.0.113.5", "2001:db8::1"} { | |
| 30 | if isForbidden(net.ParseIP(s)) { | |
| 31 | t.Errorf("%s refused", s) | |
| 32 | } | |
| 33 | } | |
| 34 | } | |