80 lines
2.4 KiB
Go
80 lines
2.4 KiB
Go
package webui
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
)
|
|
|
|
func TestRequestIPTrustedProxy(t *testing.T) {
|
|
a := &App{trustedProxies: parseTrustedProxies("10.0.0.0/8", nil)}
|
|
|
|
cases := []struct {
|
|
name string
|
|
remoteAddr string
|
|
headers map[string]string
|
|
want string
|
|
}{
|
|
{
|
|
name: "untrusted RemoteAddr ignores X-Forwarded-For entirely",
|
|
remoteAddr: "203.0.113.5:12345",
|
|
headers: map[string]string{"X-Forwarded-For": "1.2.3.4"},
|
|
want: "203.0.113.5", // a client with nothing in front of it can't spoof its own IP
|
|
},
|
|
{
|
|
name: "trusted proxy: X-Forwarded-For honored",
|
|
remoteAddr: "10.0.0.1:12345",
|
|
headers: map[string]string{"X-Forwarded-For": "198.51.100.9"},
|
|
want: "198.51.100.9",
|
|
},
|
|
{
|
|
name: "trusted proxy: walks from the right, skipping other trusted hops",
|
|
remoteAddr: "10.0.0.1:12345",
|
|
headers: map[string]string{"X-Forwarded-For": "198.51.100.9, 10.0.0.2"},
|
|
want: "198.51.100.9", // 10.0.0.2 is itself trusted (in 10.0.0.0/8) — skip it, land on the real client
|
|
},
|
|
{
|
|
name: "trusted proxy: CF-Connecting-IP preferred over X-Forwarded-For",
|
|
remoteAddr: "10.0.0.1:12345",
|
|
headers: map[string]string{"CF-Connecting-IP": "198.51.100.9", "X-Forwarded-For": "attacker-spoofed-should-be-ignored"},
|
|
want: "198.51.100.9",
|
|
},
|
|
{
|
|
name: "no trusted_proxies configured: header ignored even from that same peer",
|
|
remoteAddr: "203.0.113.5:12345",
|
|
headers: map[string]string{"X-Real-IP": "1.2.3.4"},
|
|
want: "203.0.113.5",
|
|
},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
|
req.RemoteAddr = tc.remoteAddr
|
|
for k, v := range tc.headers {
|
|
req.Header.Set(k, v)
|
|
}
|
|
if got := a.requestIP(req); got != tc.want {
|
|
t.Errorf("requestIP() = %q, want %q", got, tc.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestParseTrustedProxiesCloudflarePreset(t *testing.T) {
|
|
prefixes := parseTrustedProxies("cloudflare", nil)
|
|
if len(prefixes) != len(cloudflareRanges) {
|
|
t.Fatalf("expected %d cloudflare ranges parsed, got %d", len(cloudflareRanges), len(prefixes))
|
|
}
|
|
}
|
|
|
|
func TestParseTrustedProxiesBareIP(t *testing.T) {
|
|
prefixes := parseTrustedProxies("192.0.2.10", nil)
|
|
if len(prefixes) != 1 {
|
|
t.Fatalf("expected 1 prefix, got %d", len(prefixes))
|
|
}
|
|
if prefixes[0].Bits() != 32 {
|
|
t.Fatalf("expected a bare IPv4 to become a /32, got /%d", prefixes[0].Bits())
|
|
}
|
|
}
|