package clientip import ( "net/http/httptest" "testing" ) func TestForwardingHeadersAreBelievedOnlyFromTrustedProxies(t *testing.T) { r := httptest.NewRequest("GET", "/setup/x", nil) r.RemoteAddr = "203.0.113.9:4000" r.Header.Set("X-Forwarded-For", "10.9.9.9") r.Header.Set("X-Forwarded-Host", "evil.example") r.Header.Set("X-Forwarded-Proto", "https") r.Host = "gw.example:8080" SetTrusted(nil) if Addr(r) != "203.0.113.9" || Host(r) != "gw.example:8080" || Proto(r) != "http" { t.Errorf("believed an untrusted client: %s %s %s", Addr(r), Host(r), Proto(r)) } if bad := SetTrusted([]string{"203.0.113.0/24", "10.0.0.5", "nonsense"}); len(bad) != 1 { t.Errorf("skipped %v", bad) } r.Header.Set("X-Forwarded-For", "198.51.100.7, 10.0.0.5") if Addr(r) != "198.51.100.7" || Host(r) != "evil.example" || Proto(r) != "https" { t.Errorf("through trusted proxies: %s %s %s", Addr(r), Host(r), Proto(r)) } // A client prepending addresses gains nothing: the nearest untrusted one // is the one the proxy saw. r.Header.Set("X-Forwarded-For", "1.2.3.4, 198.51.100.7") if Addr(r) != "198.51.100.7" { t.Errorf("spoofed: %s", Addr(r)) } }