From 84707c04cb78a220084bc32e95198551c23ab0b2 Mon Sep 17 00:00:00 2001 From: Elim Tsiagbey Date: Wed, 28 Aug 2024 09:30:05 -0400 Subject: [PATCH] feat: Disable path length fallback (#5050) Add `WithDisablePathLengthFallback()` runtime option to the grpc-gateway mux HTTP server. This prevents the issue where the request method can be overridden with a `X-HTTP-Method-Override` header. --- internal/daemon/controller/gateway.go | 1 + internal/daemon/controller/gateway_test.go | 32 ++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/internal/daemon/controller/gateway.go b/internal/daemon/controller/gateway.go index a7ad3a3eb..c2bdfb756 100644 --- a/internal/daemon/controller/gateway.go +++ b/internal/daemon/controller/gateway.go @@ -65,6 +65,7 @@ func newGrpcGatewayMux() *runtime.ServeMux { }), runtime.WithErrorHandler(handlers.ErrorHandler()), runtime.WithForwardResponseOption(handlers.OutgoingResponseFilter), + runtime.WithDisablePathLengthFallback(), ) } diff --git a/internal/daemon/controller/gateway_test.go b/internal/daemon/controller/gateway_test.go index caafe7265..0566a4d82 100644 --- a/internal/daemon/controller/gateway_test.go +++ b/internal/daemon/controller/gateway_test.go @@ -4,10 +4,12 @@ package controller import ( + "bytes" "context" "fmt" "math" "net/http" + "net/http/httptest" "testing" "github.com/hashicorp/boundary/api/targets" @@ -92,3 +94,33 @@ func Test_correlationIdAnnotator(t *testing.T) { require.Len(t, corIds, 1) assert.Equal(t, corId, corIds[0]) } + +func Test_WithDisablePathLengthFallback(t *testing.T) { + ctx := context.Background() + reqPath := "/v1/example" + mux := newGrpcGatewayMux() + + assert.NotNil(t, mux) + + err := mux.HandlePath("GET", reqPath, func(w http.ResponseWriter, r *http.Request, pathParams map[string]string) { + _, _ = fmt.Fprintf(w, "%s", r.Method) + }) + assert.NoError(t, err) + + err = mux.HandlePath("POST", reqPath, func(w http.ResponseWriter, r *http.Request, pathParams map[string]string) { + _, _ = fmt.Fprintf(w, "%s", r.Method) + }) + assert.NoError(t, err) + + r, err := http.NewRequestWithContext(ctx, "POST", reqPath, bytes.NewReader(nil)) + assert.NoError(t, err) + + r.Header.Set("X-HTTP-Method-Override", "GET") + r.Header.Set("Content-Type", "application/x-www-form-urlencoded") + + w := httptest.NewRecorder() + mux.ServeHTTP(w, r) + + body := w.Body.String() + assert.Equal(t, "POST", body) +}