From d93ecdf2b4c80e6252498e00a0367f4e7e176fa2 Mon Sep 17 00:00:00 2001 From: Kim Bassett Date: Thu, 25 Jun 2026 11:04:21 -0700 Subject: [PATCH] TNZ-97927 Prevent Authorization header leaking into switchboard debug logs httputil.DumpRequest serialises all headers verbatim including Authorization: Basic , bypassing the redaction already applied by the Logger middleware. Remove the DumpRequest call and its log statement; the Logger middleware covers the same request metadata (without credentials) for every /v0 request. ai-assisted=yes [TNZ-97927](https://vmw-jira.broadcom.net/browse/TNZ-97927) Authored-by: Kim Bassett Made-with: Claude Code --- .../switchboard/api/cluster.go | 9 ------- .../switchboard/api/cluster_test.go | 26 +++++++++++++++++++ 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/github.com/cloudfoundry-incubator/switchboard/api/cluster.go b/src/github.com/cloudfoundry-incubator/switchboard/api/cluster.go index 3fd845bcf..06f73ce88 100644 --- a/src/github.com/cloudfoundry-incubator/switchboard/api/cluster.go +++ b/src/github.com/cloudfoundry-incubator/switchboard/api/cluster.go @@ -3,7 +3,6 @@ package api import ( "encoding/json" "net/http" - "net/http/httputil" "strconv" "code.cloudfoundry.org/lager/v3" @@ -61,14 +60,6 @@ func handleUpdate( return } - dumpBody := true - b, err := httputil.DumpRequest(req, dumpBody) - if err != nil { - http.Error(w, "Failed to dump http body", http.StatusInternalServerError) - return - } - - logger.Debug("API /cluster req", lager.Data{"dump": string(b)}) logger.Debug("API /cluster req form", lager.Data{"form": req.Form}) enabledStr := req.Form.Get("trafficEnabled") diff --git a/src/github.com/cloudfoundry-incubator/switchboard/api/cluster_test.go b/src/github.com/cloudfoundry-incubator/switchboard/api/cluster_test.go index aa5fd2004..cd4593bd9 100644 --- a/src/github.com/cloudfoundry-incubator/switchboard/api/cluster_test.go +++ b/src/github.com/cloudfoundry-incubator/switchboard/api/cluster_test.go @@ -1,6 +1,7 @@ package api_test import ( + "encoding/base64" "encoding/json" "net/http" "time" @@ -217,6 +218,31 @@ var _ = Describe("ClusterEndpoint", func() { }) }) + Context("when a PATCH request includes an Authorization header", func() { + It("does not log the Authorization header credentials", func() { + const password = "supersecretpassword" + encodedCreds := base64.StdEncoding.EncodeToString( + []byte("admin:" + password), + ) + + req, err := http.NewRequest( + "PATCH", + server.URL()+"?trafficEnabled=true", + nil, + ) + Expect(err).NotTo(HaveOccurred()) + req.SetBasicAuth("admin", password) + + client := &http.Client{} + _, err = client.Do(req) + Expect(err).NotTo(HaveOccurred()) + + logContents := testLogger.Buffer().Contents() + Expect(logContents).ToNot(ContainSubstring(encodedCreds), + "Authorization header base64 value must not appear in logs") + }) + }) + Describe("POST", func() { It("returns http 405 - Method not allowed", func() { req, err := http.NewRequest("POST", server.URL(), nil)