refactor(recovery): extract Authorization header masking into maskAuthorization func (#4143)

* refactor(recovery): extract Authorization header masking into maskAuthorization func

* test(recovery): Add a test for maskAuthorization
This commit is contained in:
OHZEKI Naoki 2025-06-02 13:38:19 +09:00 committed by GitHub
parent 3c12d2a80e
commit e30123ad73
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 29 additions and 6 deletions

View File

@ -70,12 +70,7 @@ func CustomRecoveryWithWriter(out io.Writer, handle RecoveryFunc) HandlerFunc {
stack := stack(3) stack := stack(3)
httpRequest, _ := httputil.DumpRequest(c.Request, false) httpRequest, _ := httputil.DumpRequest(c.Request, false)
headers := strings.Split(string(httpRequest), "\r\n") headers := strings.Split(string(httpRequest), "\r\n")
for idx, header := range headers { maskAuthorization(headers)
key, _, _ := strings.Cut(header, ":")
if key == "Authorization" {
headers[idx] = key + ": *"
}
}
headersToStr := strings.Join(headers, "\r\n") headersToStr := strings.Join(headers, "\r\n")
if brokenPipe { if brokenPipe {
logger.Printf("%s\n%s%s", err, headersToStr, reset) logger.Printf("%s\n%s%s", err, headersToStr, reset)
@ -131,6 +126,16 @@ func stack(skip int) []byte {
return buf.Bytes() return buf.Bytes()
} }
// maskAuthorization replaces any "Authorization: <token>" header with "Authorization: *", hiding sensitive credentials.
func maskAuthorization(headers []string) {
for idx, header := range headers {
key, _, _ := strings.Cut(header, ":")
if strings.EqualFold(key, "Authorization") {
headers[idx] = key + ": *"
}
}
}
// source returns a space-trimmed slice of the n'th line. // source returns a space-trimmed slice of the n'th line.
func source(lines [][]byte, n int) []byte { func source(lines [][]byte, n int) []byte {
n-- // in stack trace, lines are 1-indexed but our array is 0-indexed n-- // in stack trace, lines are 1-indexed but our array is 0-indexed

View File

@ -88,6 +88,24 @@ func TestPanicWithAbort(t *testing.T) {
assert.Equal(t, http.StatusBadRequest, w.Code) assert.Equal(t, http.StatusBadRequest, w.Code)
} }
func TestMaskAuthorization(t *testing.T) {
secret := "Bearer aaaabbbbccccddddeeeeffff"
headers := []string{
"Host: www.example.com",
"Authorization: " + secret,
"User-Agent: curl/7.51.0",
"Accept: */*",
"Content-Type: application/json",
"Content-Length: 1",
}
maskAuthorization(headers)
for _, h := range headers {
assert.NotContains(t, h, secret)
}
assert.Contains(t, headers, "Authorization: *")
}
func TestSource(t *testing.T) { func TestSource(t *testing.T) {
bs := source(nil, 0) bs := source(nil, 0)
assert.Equal(t, dunnoBytes, bs) assert.Equal(t, dunnoBytes, bs)