Files

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())
}
}