From ae0c4c45c0dc4f92eca189bdbd0999863b1800c1 Mon Sep 17 00:00:00 2001 From: winstoncrooker Date: Mon, 13 Jul 2026 21:23:22 -0700 Subject: [PATCH] Strip custom credential headers on cross-host redirects The main HTTP client follows redirects but net/http only strips the standard sensitive headers (Authorization, Cookie) when a redirect changes host. The custom cloud-provider token headers (X-Databricks-Azure-SP-Management-Token, X-Databricks-GCP-SA-Access-Token) were therefore forwarded to a different host on a cross-host redirect. Add a CheckRedirect to the main client that drops these headers when a redirect changes host, matching how net/http handles Authorization and how the Azure tenant-fetch client already avoids following redirects. Signed-off-by: winstoncrooker --- NEXT_CHANGELOG.md | 1 + httpclient/api_client.go | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/NEXT_CHANGELOG.md b/NEXT_CHANGELOG.md index f7ca08f74..818cfcbb3 100644 --- a/NEXT_CHANGELOG.md +++ b/NEXT_CHANGELOG.md @@ -7,6 +7,7 @@ ### New Features and Improvements ### Bug Fixes +- Strip custom Databricks credential headers (`X-Databricks-Azure-SP-Management-Token`, `X-Databricks-GCP-SA-Access-Token`) on cross-host redirects, matching how `net/http` handles the `Authorization` header. ### Documentation diff --git a/httpclient/api_client.go b/httpclient/api_client.go index e3ac428e8..224185b08 100644 --- a/httpclient/api_client.go +++ b/httpclient/api_client.go @@ -24,6 +24,15 @@ import ( type RequestVisitor func(*http.Request) error +// sensitiveCrossHostHeaders are custom Databricks auth headers carrying credentials that must +// not be forwarded across a host boundary on redirect (net/http only strips the standard +// sensitive headers such as Authorization on cross-host redirects). +var sensitiveCrossHostHeaders = []string{ + "X-Databricks-Azure-SP-Management-Token", + "X-Databricks-GCP-SA-Access-Token", + "X-Databricks-Azure-Workspace-Resource-Id", +} + type ClientConfig struct { AuthVisitor RequestVisitor Visitors []RequestVisitor @@ -157,6 +166,21 @@ func NewApiClient(cfg ClientConfig) *ApiClient { // progress (e.g. on a slower network connection). Timeout: 0, Transport: transport, + // net/http strips sensitive headers (Authorization, Cookie, ...) when a redirect + // crosses to a different host, but it does not strip our custom cloud-provider token + // headers. Drop those on a cross-host redirect so credentials are not sent to a host + // other than the one they were intended for. + CheckRedirect: func(req *http.Request, via []*http.Request) error { + if len(via) >= 10 { + return errors.New("stopped after 10 redirects") + } + if len(via) > 0 && req.URL.Host != via[0].URL.Host { + for _, h := range sensitiveCrossHostHeaders { + req.Header.Del(h) + } + } + return nil + }, }, } }