From 689d090711762a4ab315320d706d3c9e3b225d3d Mon Sep 17 00:00:00 2001 From: Ted Yu Date: Tue, 13 Aug 2019 09:36:13 -0700 Subject: [PATCH] Hide bearer token in logs Kubernetes-commit: 010d8382642119c73cb2405286b347c08d704287 --- transport/round_trippers.go | 33 +++++++++++++ transport/round_trippers_test.go | 85 ++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) diff --git a/transport/round_trippers.go b/transport/round_trippers.go index 117a9c8c..844ee9a2 100644 --- a/transport/round_trippers.go +++ b/transport/round_trippers.go @@ -409,6 +409,38 @@ func (rt *debuggingRoundTripper) CancelRequest(req *http.Request) { } } +var knownAuthTypes = map[string]bool{ + "bearer": true, + "basic": true, + "negotiate": true, +} + +// maskValue masks credential content from authorization headers +// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization +func maskValue(key string, value string) string { + if !strings.EqualFold(key, "Authorization") { + return value + } + if len(value) == 0 { + return "" + } + var authType string + if i := strings.Index(value, " "); i > 0 { + authType = value[0:i] + } else { + authType = value + } + if !knownAuthTypes[strings.ToLower(authType)] { + return "" + } + if len(value) > len(authType)+1 { + value = authType + " " + } else { + value = authType + } + return value +} + func (rt *debuggingRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { reqInfo := newRequestInfo(req) @@ -423,6 +455,7 @@ func (rt *debuggingRoundTripper) RoundTrip(req *http.Request) (*http.Response, e klog.Infof("Request Headers:") for key, values := range reqInfo.RequestHeaders { for _, value := range values { + value = maskValue(key, value) klog.Infof(" %s: %s", key, value) } } diff --git a/transport/round_trippers_test.go b/transport/round_trippers_test.go index abe5ab53..ac8de240 100644 --- a/transport/round_trippers_test.go +++ b/transport/round_trippers_test.go @@ -35,6 +35,91 @@ func (rt *testRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) return rt.Response, rt.Err } +func TestMaskValue(t *testing.T) { + tcs := []struct { + key string + value string + expected string + }{ + { + key: "Authorization", + value: "Basic YWxhZGRpbjpvcGVuc2VzYW1l", + expected: "Basic ", + }, + { + key: "Authorization", + value: "basic", + expected: "basic", + }, + { + key: "Authorization", + value: "Basic", + expected: "Basic", + }, + { + key: "Authorization", + value: "Bearer cn389ncoiwuencr", + expected: "Bearer ", + }, + { + key: "Authorization", + value: "Bearer", + expected: "Bearer", + }, + { + key: "Authorization", + value: "bearer", + expected: "bearer", + }, + { + key: "Authorization", + value: "bearer ", + expected: "bearer", + }, + { + key: "Authorization", + value: "Negotiate cn389ncoiwuencr", + expected: "Negotiate ", + }, + { + key: "ABC", + value: "Negotiate cn389ncoiwuencr", + expected: "Negotiate cn389ncoiwuencr", + }, + { + key: "Authorization", + value: "Negotiate", + expected: "Negotiate", + }, + { + key: "Authorization", + value: "Negotiate ", + expected: "Negotiate", + }, + { + key: "Authorization", + value: "negotiate", + expected: "negotiate", + }, + { + key: "Authorization", + value: "abc cn389ncoiwuencr", + expected: "", + }, + { + key: "Authorization", + value: "", + expected: "", + }, + } + for _, tc := range tcs { + maskedValue := maskValue(tc.key, tc.value) + if tc.expected != maskedValue { + t.Errorf("unexpected value %s, given %s.", maskedValue, tc.value) + } + } +} + func TestBearerAuthRoundTripper(t *testing.T) { rt := &testRoundTripper{} req := &http.Request{}