redact sensitive headers in HTTP debug logs (#5873)
This commit is contained in:
@@ -14,6 +14,28 @@ const (
|
||||
maxDumpedRequestBodySize = 10 * 1024
|
||||
)
|
||||
|
||||
var requestHeadersToRedact = map[string]struct{}{
|
||||
"Authorization": {},
|
||||
"Cookie": {},
|
||||
"Proxy-Authorization": {},
|
||||
"Set-Cookie": {},
|
||||
"X-Api-Key": {},
|
||||
"X-Auth-Token": {},
|
||||
}
|
||||
|
||||
func cloneRequestForLogging(r *http.Request) *http.Request {
|
||||
clone := r.Clone(r.Context())
|
||||
clone.Header = r.Header.Clone()
|
||||
|
||||
for header := range requestHeadersToRedact {
|
||||
if clone.Header.Get(header) != "" {
|
||||
clone.Header.Set(header, "<redacted>")
|
||||
}
|
||||
}
|
||||
|
||||
return clone
|
||||
}
|
||||
|
||||
func dumpRequestLimited(r *http.Request) ([]byte, error) {
|
||||
peek, err := io.ReadAll(io.LimitReader(r.Body, maxDumpedRequestBodySize+1))
|
||||
if err != nil {
|
||||
@@ -28,8 +50,9 @@ func dumpRequestLimited(r *http.Request) ([]byte, error) {
|
||||
|
||||
original := r.Body
|
||||
r.Body = io.NopCloser(bytes.NewReader(capped))
|
||||
clone := cloneRequestForLogging(r)
|
||||
|
||||
dump, dumpErr := httputil.DumpRequest(r, true)
|
||||
dump, dumpErr := httputil.DumpRequest(clone, true)
|
||||
|
||||
r.Body = io.NopCloser(io.MultiReader(bytes.NewReader(peek), original))
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package httpp
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestDumpRequestLimitedRedactsSensitiveHeaders(t *testing.T) {
|
||||
req, err := http.NewRequest(http.MethodPost, "http://localhost/test", strings.NewReader("request body"))
|
||||
require.NoError(t, err)
|
||||
|
||||
req.Header.Set("Authorization", "Bearer secret-token")
|
||||
req.Header.Set("Cookie", "session=secret-cookie")
|
||||
req.Header.Set("Proxy-Authorization", "Bearer proxy-secret")
|
||||
req.Header.Set("X-Api-Key", "secret-api-key")
|
||||
req.Header.Set("X-Auth-Token", "secret-auth-token")
|
||||
|
||||
dump, err := dumpRequestLimited(req)
|
||||
require.NoError(t, err)
|
||||
|
||||
dumpStr := string(dump)
|
||||
require.Contains(t, dumpStr, "Authorization: <redacted>")
|
||||
require.Contains(t, dumpStr, "Cookie: <redacted>")
|
||||
require.Contains(t, dumpStr, "Proxy-Authorization: <redacted>")
|
||||
require.Contains(t, dumpStr, "X-Api-Key: <redacted>")
|
||||
require.Contains(t, dumpStr, "X-Auth-Token: <redacted>")
|
||||
require.NotContains(t, dumpStr, "secret-token")
|
||||
require.NotContains(t, dumpStr, "secret-cookie")
|
||||
require.NotContains(t, dumpStr, "proxy-secret")
|
||||
require.NotContains(t, dumpStr, "secret-api-key")
|
||||
require.NotContains(t, dumpStr, "secret-auth-token")
|
||||
require.Contains(t, dumpStr, "request body")
|
||||
|
||||
require.Equal(t, "Bearer secret-token", req.Header.Get("Authorization"))
|
||||
|
||||
body, err := io.ReadAll(req.Body)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "request body", string(body))
|
||||
}
|
||||
Reference in New Issue
Block a user