package forwarder import ( "net/http" "net/http/httptest" "net/url" "testing" "time" ) func TestForwardAssertionBindsMethodPathAndTarget(t *testing.T) { secret := []byte("0123456789abcdef0123456789abcdef") now := time.Unix(1_786_536_000, 0) forwarder, err := New(Config{ NodeID: "node_source", Secret: secret, Endpoints: map[string]string{}, HTTPClient: http.DefaultClient, WebSocketDialer: nil, Now: func() time.Time { return now }, ClientCertFile: "missing", ClientKeyFile: "missing", CAFile: "missing", }) if err == nil { // A nil WebSocket dialer intentionally requires real mTLS files. t.Fatal("forwarder accepted a partial injected transport") } forwarder = &Forwarder{nodeID: "node_source", secret: secret, now: func() time.Time { return now }} request := httptest.NewRequest(http.MethodPost, "https://relay.example/ws/daemon?generation=2", nil) forwarder.sign(request.Header, request.Method, request.URL.RequestURI(), "node_target") if err := VerifyIncoming(request, "node_target", secret, now); err != nil { t.Fatal(err) } request.URL.Path = "/ws/phone" if err := VerifyIncoming(request, "node_target", secret, now); err == nil { t.Fatal("forward assertion survived path substitution") } } func TestEndpointReferenceCannotSelectArbitraryURL(t *testing.T) { forwarder := &Forwarder{endpoints: map[string]*url.URL{}} if _, err := forwarder.endpoint("https://evil.example"); err == nil { t.Fatal("unconfigured URL was accepted as an endpoint reference") } }