diff --git a/internal/api/handlers_blocklist.go b/internal/api/handlers_blocklist.go index 43dcd0f..30bed28 100644 --- a/internal/api/handlers_blocklist.go +++ b/internal/api/handlers_blocklist.go @@ -15,7 +15,8 @@ import ( const ( // headerMarker separates the URI path from the optional header list in the URL. - headerMarker = "/_headers/" + headerMarker = "/_headers/" + maxMaskedChars = 10 ) // parseEntityFromWildcard splits the Fiber wildcard parameter (everything after @@ -144,9 +145,16 @@ func maskHeader(headerValue string, expr *regexp.Regexp) string { return headerValue } g1Start, g1End := locs[2], locs[3] + // if the masked portion is > 10 chars, then we cut it and add `...` + threeDots := "" + endRepeat := len(headerValue) - g1End + if endRepeat > maxMaskedChars { + endRepeat = maxMaskedChars + threeDots = "..." + } return strings.Repeat("*", g1Start) + headerValue[g1Start:g1End] + - strings.Repeat("*", len(headerValue)-g1End) + strings.Repeat("*", endRepeat) + threeDots } // handleBlockEntityAdd handles POST /v1/blocked-entity/:ip/_path/*. diff --git a/internal/api/handlers_blocklist_test.go b/internal/api/handlers_blocklist_test.go index f3fe845..126e8da 100644 --- a/internal/api/handlers_blocklist_test.go +++ b/internal/api/handlers_blocklist_test.go @@ -518,14 +518,14 @@ func TestMaskHeader_ApiKeyPattern(t *testing.T) { // Typical use-case from the docs: show first 3 chars, mask the rest. expr := regexp.MustCompile(`^(.{0,3}).*$`) got := maskHeader("sk_live_xyz9876", expr) - assert.Equal(t, "sk_************", got) + assert.Equal(t, "sk_**********...", got) } func TestMaskHeader_BearerToken(t *testing.T) { expr := regexp.MustCompile(`^(Bearer .{0,3}).*$`) got := maskHeader("Bearer sk_test_abc123", expr) // "Bearer sk" (9 chars kept) + 11 stars - assert.Equal(t, "Bearer sk_***********", got) + assert.Equal(t, "Bearer sk_**********...", got) } func TestMaskHeader_NoMatch_ReturnsOriginal(t *testing.T) { @@ -597,7 +597,7 @@ func TestBlockEntityList_HeaderRedactionApplied(t *testing.T) { require.Len(t, entries, 1) got := entries[0].Headers["X-Api-Key"] - assert.Equal(t, "abc************", got, "first 3 chars kept, rest masked") + assert.Equal(t, "abc**********...", got, "first 3 chars kept, rest masked") } func TestBlockEntityList_UnredactedHeadersPassThrough(t *testing.T) {