From d7256c7af7c3d9bf983018aece61546368ed5bed Mon Sep 17 00:00:00 2001 From: henrygd Date: Wed, 26 Aug 2026 12:47:23 -0400 Subject: [PATCH] fix: widen coverage of internal ip space in `isInternalIP` --- internal/alerts/alerts_api.go | 12 +++++++++++- internal/alerts/alerts_api_test.go | 18 +++++++++++++++--- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/internal/alerts/alerts_api.go b/internal/alerts/alerts_api.go index feb0587c..a5ef5d32 100644 --- a/internal/alerts/alerts_api.go +++ b/internal/alerts/alerts_api.go @@ -203,6 +203,16 @@ func isInternalURL(rawURL string) (bool, error) { return false, nil } +var cgnatNetwork = &net.IPNet{ + IP: net.IPv4(100, 64, 0, 0), + Mask: net.CIDRMask(10, 32), +} + func isInternalIP(ip net.IP) bool { - return ip.IsPrivate() || ip.IsLoopback() || ip.IsUnspecified() + return ip.IsPrivate() || + ip.IsLoopback() || + ip.IsUnspecified() || + ip.IsLinkLocalUnicast() || + ip.IsMulticast() || + cgnatNetwork.Contains(ip) } diff --git a/internal/alerts/alerts_api_test.go b/internal/alerts/alerts_api_test.go index 326e8f35..6f615e8d 100644 --- a/internal/alerts/alerts_api_test.go +++ b/internal/alerts/alerts_api_test.go @@ -36,11 +36,23 @@ func TestIsInternalURL(t *testing.T) { internal bool }{ {name: "loopback ipv4", url: "generic://127.0.0.1", internal: true}, + {name: "private ipv4", url: "generic://10.0.0.1", internal: true}, {name: "localhost hostname", url: "generic://localhost", internal: true}, - {name: "localhost hostname", url: "generic+http://localhost/api/v1/postStuff", internal: true}, - {name: "localhost hostname", url: "generic+http://127.0.0.1:8080/api/v1/postStuff", internal: true}, - {name: "localhost hostname", url: "generic+https://beszel.dev/api/v1/postStuff", internal: false}, + {name: "localhost with path", url: "generic+http://localhost/api/v1/postStuff", internal: true}, + {name: "loopback with port and path", url: "generic+http://127.0.0.1:8080/api/v1/postStuff", internal: true}, + {name: "public hostname", url: "generic+https://beszel.dev/api/v1/postStuff", internal: false}, + {name: "cloud metadata ipv4", url: "generic://169.254.169.254", internal: true}, + {name: "link-local ipv4", url: "generic://169.254.1.1", internal: true}, + {name: "link-local ipv6", url: "generic://[fe80::1]", internal: true}, + {name: "mapped link-local ipv4", url: "generic://[::ffff:169.254.169.254]", internal: true}, + {name: "cgnat lower boundary", url: "generic://100.64.0.0", internal: true}, + {name: "cgnat upper boundary", url: "generic://100.127.255.255", internal: true}, + {name: "below cgnat", url: "generic://100.63.255.255", internal: false}, + {name: "above cgnat", url: "generic://100.128.0.0", internal: false}, + {name: "multicast ipv4", url: "generic://224.0.0.1", internal: true}, + {name: "multicast ipv6", url: "generic://[ff02::1]", internal: true}, {name: "public ipv4", url: "generic://8.8.8.8", internal: false}, + {name: "public ipv6", url: "generic://[2001:4860:4860::8888]", internal: false}, {name: "token style service url", url: "discord://abc123@123456789", internal: false}, {name: "single label service url", url: "slack://token@team/channel", internal: false}, }