Fix redactSecretsFromURL matching params with prefixed names

The function was using substring matching for sensitive param names,
causing parameters like "extra_token" or "myapikey" to be incorrectly
redacted when they matched "token=" or "apikey=" as substrings.

Now checks for proper boundary characters (? or &) before matching,
so only actual parameter names are redacted.

Related to ADA knowledge entry: "Query param redaction uses substring matching"
This commit is contained in:
rcourtman 2025-11-29 22:03:15 +00:00
parent e2cdcb7b3e
commit 1b3effcb10
2 changed files with 42 additions and 4 deletions

View file

@ -482,17 +482,39 @@ func redactSecretsFromURL(urlStr string) string {
}
// Redact query parameters with sensitive names
if idx := strings.Index(urlStr, "?"); idx != -1 {
if qIdx := strings.Index(urlStr, "?"); qIdx != -1 {
sensitiveParams := []string{"token", "apikey", "api_key", "key", "secret", "password"}
for _, param := range sensitiveParams {
pattern := param + "="
if paramIdx := strings.Index(urlStr, pattern); paramIdx != -1 {
// Search for the pattern after the query string starts
searchStart := qIdx
for {
paramIdx := strings.Index(urlStr[searchStart:], pattern)
if paramIdx == -1 {
break
}
paramIdx += searchStart // Convert to absolute index
// Check that we're at a parameter boundary (after ? or &)
if paramIdx > 0 {
prevChar := urlStr[paramIdx-1]
if prevChar != '?' && prevChar != '&' {
// Not at a boundary - this is part of another param name
// Move past this match and continue searching
searchStart = paramIdx + len(pattern)
continue
}
}
// Valid match - redact the value
start := paramIdx + len(pattern)
end := start
for end < len(urlStr) && urlStr[end] != '&' && urlStr[end] != '#' {
end++
}
urlStr = urlStr[:start] + "REDACTED" + urlStr[end:]
// After modification, continue from after the inserted REDACTED
searchStart = start + len("REDACTED")
}
}
}

View file

@ -109,8 +109,24 @@ func TestRedactSecretsFromURL(t *testing.T) {
},
{
name: "combined telegram and query param secrets",
input: "https://api.telegram.org/bot123:token/send?extra_token=abc",
expected: "https://api.telegram.org/botREDACTED/send?extra_token=REDACTED",
input: "https://api.telegram.org/bot123:token/send?token=abc",
expected: "https://api.telegram.org/botREDACTED/send?token=REDACTED",
},
// Boundary checking - prefixed params should NOT be redacted
{
name: "prefixed param name should not match",
input: "https://example.com/api?extra_token=abc&myapikey=xyz",
expected: "https://example.com/api?extra_token=abc&myapikey=xyz",
},
{
name: "prefixed param with real sensitive param",
input: "https://example.com/api?extra_token=abc&token=secret",
expected: "https://example.com/api?extra_token=abc&token=REDACTED",
},
{
name: "multiple prefixed params unchanged",
input: "https://example.com/api?mytoken=a&yourkey=b&thesecret=c",
expected: "https://example.com/api?mytoken=a&yourkey=b&thesecret=c",
},
}