Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions internal/api/handlers_blocklist.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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/*.
Expand Down
6 changes: 3 additions & 3 deletions internal/api/handlers_blocklist_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down
Loading