From 5819a6c4552b1c3c37f48405ad1dc7d7b4681a8c Mon Sep 17 00:00:00 2001 From: Ajay Kelkar Date: Thu, 8 Sep 2022 10:41:17 +0200 Subject: [PATCH] feat: helper to extract ip address that isn't on an exclusion list (#593) --- httpx/client_info.go | 34 ++++++++++++++++++++++++++++++++++ httpx/client_info_test.go | 22 ++++++++++++++++++++++ httpx/private_ip_validator.go | 20 +++++++++++--------- stringsx/ptr.go | 5 +++++ stringsx/ptr_test.go | 11 +++++++++++ 5 files changed, 83 insertions(+), 9 deletions(-) create mode 100644 httpx/client_info.go create mode 100644 httpx/client_info_test.go create mode 100644 stringsx/ptr.go create mode 100644 stringsx/ptr_test.go diff --git a/httpx/client_info.go b/httpx/client_info.go new file mode 100644 index 00000000..cde03185 --- /dev/null +++ b/httpx/client_info.go @@ -0,0 +1,34 @@ +package httpx + +import ( + "net" + "strings" +) + +func GetClientIPAddress(ipAddresses []string, exclude []string) (string, error) { + var res string + + for i := len(ipAddresses) - 1; i >= 0; i-- { + var isExcluded bool + ip := strings.TrimSpace(ipAddresses[i]) + + for _, j := range exclude { + _, cidr, err := net.ParseCIDR(j) + if err != nil { + return "", err + } + + if cidr.Contains(net.ParseIP(ip)) { + isExcluded = true + break + } + } + + if !isExcluded { + res = ip + break + } + } + + return res, nil +} diff --git a/httpx/client_info_test.go b/httpx/client_info_test.go new file mode 100644 index 00000000..270257c9 --- /dev/null +++ b/httpx/client_info_test.go @@ -0,0 +1,22 @@ +package httpx + +import ( + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "strings" + "testing" +) + +func TestIgnoresInternalIPs(t *testing.T) { + input := "54.155.246.232,10.145.1.10" + + res, err := GetClientIPAddress(strings.Split(input, ","), InternalIPSet) + require.NoError(t, err) + assert.Equal(t, "54.155.246.232", res) +} + +func TestEmptyInputArray(t *testing.T) { + res, err := GetClientIPAddress([]string{}, InternalIPSet) + require.NoError(t, err) + assert.Equal(t, "", res) +} diff --git a/httpx/private_ip_validator.go b/httpx/private_ip_validator.go index 5760694f..914fd143 100644 --- a/httpx/private_ip_validator.go +++ b/httpx/private_ip_validator.go @@ -11,6 +11,16 @@ import ( "github.com/pkg/errors" ) +var InternalIPSet = []string{ + "127.0.0.0/8", + "10.0.0.0/8", + "172.16.0.0/12", + "192.168.0.0/16", + "fd47:1ed0:805d:59f0::/64", + "fc00::/7", + "::1/128", +} + // ErrPrivateIPAddressDisallowed is returned when a private IP address is disallowed. type ErrPrivateIPAddressDisallowed error @@ -64,15 +74,7 @@ func DisallowIPPrivateAddresses(ipOrHostnameOrURL string) error { ips = append(ips, ip) } - for _, disabled := range []string{ - "127.0.0.0/8", - "10.0.0.0/8", - "172.16.0.0/12", - "192.168.0.0/16", - "fd47:1ed0:805d:59f0::/64", - "fc00::/7", - "::1/128", - } { + for _, disabled := range InternalIPSet { _, cidr, err := net.ParseCIDR(disabled) if err != nil { return err diff --git a/stringsx/ptr.go b/stringsx/ptr.go new file mode 100644 index 00000000..4e9d464b --- /dev/null +++ b/stringsx/ptr.go @@ -0,0 +1,5 @@ +package stringsx + +func GetPointer(s string) *string { + return &s +} diff --git a/stringsx/ptr_test.go b/stringsx/ptr_test.go new file mode 100644 index 00000000..46432f02 --- /dev/null +++ b/stringsx/ptr_test.go @@ -0,0 +1,11 @@ +package stringsx + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestGetPointer(t *testing.T) { + s := "TestString" + assert.Equal(t, &s, GetPointer(s)) +}