Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion internal/httpgetter/html_meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,15 @@ func resolveAllowedIPs(ctx context.Context, host string) ([]net.IP, error) {
return ips, nil
}

// sharedAddressSpace is RFC 6598 (100.64.0.0/10). It is not covered by
// net.IP.IsPrivate, but it is unroutable on the public internet and some
// clouds expose their instance-metadata service inside it (e.g. Alibaba
// Cloud at 100.100.100.200), so it must be treated as internal.
var sharedAddressSpace = &net.IPNet{IP: net.IPv4(100, 64, 0, 0), Mask: net.CIDRMask(10, 32)}

func isInternalIP(ip net.IP) bool {
return ip.IsLoopback() || ip.IsPrivate() || ip.IsLinkLocalUnicast() || ip.IsUnspecified()
return ip.IsLoopback() || ip.IsPrivate() || ip.IsLinkLocalUnicast() ||
ip.IsLinkLocalMulticast() || ip.IsUnspecified() || sharedAddressSpace.Contains(ip)
}

func validateURL(urlStr string) error {
Expand Down
29 changes: 29 additions & 0 deletions internal/httpgetter/html_meta_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,35 @@ func TestGetHTMLMetaForInternal(t *testing.T) {
}
}

func TestIsInternalIP(t *testing.T) {
internal := []string{
"127.0.0.1", // loopback
"10.0.0.1", // RFC 1918
"192.168.1.1", // RFC 1918
"169.254.169.254", // link-local (cloud metadata)
"100.64.0.1", // RFC 6598 lower bound
"100.100.100.200", // Alibaba Cloud instance metadata
"100.127.255.255", // RFC 6598 upper bound
"::1", // IPv6 loopback
"fd00::1", // IPv6 unique local
"::ffff:127.0.0.1", // IPv4-mapped loopback
"::ffff:100.64.0.1", // IPv4-mapped shared address space
}
for _, s := range internal {
require.Truef(t, isInternalIP(net.ParseIP(s)), "expected %s to be internal", s)
}

external := []string{
"93.184.216.34", // example.com
"8.8.8.8", // public DNS
"100.63.255.255", // just below RFC 6598
"100.128.0.0", // just above RFC 6598
}
for _, s := range external {
require.Falsef(t, isInternalIP(net.ParseIP(s)), "expected %s to be external", s)
}
}

func TestHTTPClientHasTimeout(t *testing.T) {
require.NotZero(t, httpClient.Timeout)
}
Expand Down