package netguard import ( "context" "net" "net/http" "net/http/httptest" "testing" "time" ) func TestIsPublicIP(t *testing.T) { cases := map[string]bool{ "8.8.8.8": true, "1.1.1.1": true, "127.0.0.1": false, "10.0.0.1": false, "172.16.0.1": false, "192.168.1.1": false, "169.254.169.254": false, // cloud metadata "100.64.0.1": false, // CGNAT "0.0.0.0": false, "::1": false, "fe80::1": false, "fc00::1": false, "2606:4700::1111": true, } for s, want := range cases { ip := net.ParseIP(s) if ip == nil { t.Fatalf("bad test IP %q", s) } if got := IsPublicIP(ip); got != want { t.Errorf("IsPublicIP(%q) = %v, want %v", s, got, want) } } } func TestSafeHTTPClientBlocksLoopback(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("ok")) })) defer srv.Close() client := NewSafeHTTPClient(5*time.Second, false) _, err := client.Get(srv.URL) if err == nil { t.Fatal("expected request to loopback server to be blocked") } } func TestSafeHTTPClientAllowsLoopbackWhenPermitted(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("ok")) })) defer srv.Close() client := NewSafeHTTPClient(5*time.Second, true) resp, err := client.Get(srv.URL) if err != nil { t.Fatalf("expected request to loopback server to succeed: %v", err) } resp.Body.Close() } func TestSafeHTTPClientBlocksRedirectToPrivate(t *testing.T) { blocked := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("should never be reached")) })) defer blocked.Close() // A "public-looking" server (still loopback in this test, but with // AllowPrivateNetworks=false the initial dial to it would itself be // blocked — so instead verify redirect scheme enforcement directly // via CheckRedirect using a context that never dials at all). client := NewSafeHTTPClient(5*time.Second, false) req, _ := http.NewRequestWithContext(context.Background(), http.MethodGet, blocked.URL, nil) if err := client.CheckRedirect(req, nil); err != nil { t.Fatalf("unexpected error for allowed scheme: %v", err) } req.URL.Scheme = "file" if err := client.CheckRedirect(req, nil); err == nil { t.Fatal("expected file:// redirect to be rejected") } }