mirror of
https://github.com/CJackHwang/ds2api.git
synced 2026-05-23 10:57:44 +08:00
fix toolcall inline code and query redaction
This commit is contained in:
@@ -185,8 +185,8 @@ func redactSensitiveQueryParams(u *url.URL) (string, bool) {
|
||||
return "", false
|
||||
}
|
||||
values, err := url.ParseQuery(u.RawQuery)
|
||||
if err != nil && len(values) == 0 {
|
||||
return "", false
|
||||
if err != nil {
|
||||
return redactSensitiveRawQueryParams(u.RawQuery)
|
||||
}
|
||||
changed := false
|
||||
for name, vals := range values {
|
||||
@@ -205,6 +205,57 @@ func redactSensitiveQueryParams(u *url.URL) (string, bool) {
|
||||
return values.Encode(), true
|
||||
}
|
||||
|
||||
func redactSensitiveRawQueryParams(rawQuery string) (string, bool) {
|
||||
if rawQuery == "" {
|
||||
return "", false
|
||||
}
|
||||
var b strings.Builder
|
||||
b.Grow(len(rawQuery))
|
||||
changed := false
|
||||
start := 0
|
||||
for i := 0; i <= len(rawQuery); i++ {
|
||||
if i < len(rawQuery) && rawQuery[i] != '&' && rawQuery[i] != ';' {
|
||||
continue
|
||||
}
|
||||
segment := rawQuery[start:i]
|
||||
b.WriteString(redactSensitiveRawQuerySegment(segment, &changed))
|
||||
if i < len(rawQuery) {
|
||||
b.WriteByte(rawQuery[i])
|
||||
}
|
||||
start = i + 1
|
||||
}
|
||||
if !changed {
|
||||
return "", false
|
||||
}
|
||||
return b.String(), true
|
||||
}
|
||||
|
||||
func redactSensitiveRawQuerySegment(segment string, changed *bool) string {
|
||||
if segment == "" {
|
||||
return segment
|
||||
}
|
||||
name := segment
|
||||
valueStart := -1
|
||||
if eq := strings.IndexByte(segment, '='); eq >= 0 {
|
||||
name = segment[:eq]
|
||||
valueStart = eq + 1
|
||||
}
|
||||
decodedName, err := url.QueryUnescape(name)
|
||||
if err != nil {
|
||||
decodedName = name
|
||||
}
|
||||
if !isSensitiveQueryParam(decodedName) {
|
||||
return segment
|
||||
}
|
||||
if changed != nil {
|
||||
*changed = true
|
||||
}
|
||||
if valueStart < 0 {
|
||||
return name + "=REDACTED"
|
||||
}
|
||||
return segment[:valueStart] + "REDACTED"
|
||||
}
|
||||
|
||||
func isSensitiveQueryParam(name string) bool {
|
||||
return strings.EqualFold(name, "key") || strings.EqualFold(name, "api_key")
|
||||
}
|
||||
|
||||
@@ -45,3 +45,60 @@ func TestFilteredLogFormatterRedactsSensitiveQueryParams(t *testing.T) {
|
||||
t.Fatalf("request was mutated, RawQuery = %q", req.URL.RawQuery)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilteredLogFormatterRedactsSensitiveQueryParamsWhenMalformed(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
target string
|
||||
secrets []string
|
||||
redacted []string
|
||||
preserved []string
|
||||
}{
|
||||
{
|
||||
name: "semicolon separator",
|
||||
target: "/v1beta/models/gemini-2.5-pro:generateContent?key=caller-secret;alt=sse",
|
||||
secrets: []string{"caller-secret"},
|
||||
redacted: []string{"key=REDACTED"},
|
||||
preserved: []string{"alt=sse"},
|
||||
},
|
||||
{
|
||||
name: "bad escape in sensitive value",
|
||||
target: "/v1beta/models/gemini-2.5-pro:generateContent?api_key=second-secret%ZZ",
|
||||
secrets: []string{"second-secret"},
|
||||
redacted: []string{"api_key=REDACTED"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
formatter := &filteredLogFormatter{
|
||||
base: &middleware.DefaultLogFormatter{
|
||||
Logger: log.New(&buf, "", 0),
|
||||
NoColor: true,
|
||||
},
|
||||
}
|
||||
req := httptest.NewRequest(http.MethodPost, tt.target, nil)
|
||||
|
||||
entry := formatter.NewLogEntry(req)
|
||||
entry.Write(http.StatusOK, 0, http.Header{}, time.Millisecond, nil)
|
||||
|
||||
got := buf.String()
|
||||
for _, secret := range tt.secrets {
|
||||
if strings.Contains(got, secret) {
|
||||
t.Fatalf("log line contains sensitive query value %q: %s", secret, got)
|
||||
}
|
||||
}
|
||||
for _, want := range tt.redacted {
|
||||
if !strings.Contains(got, want) {
|
||||
t.Fatalf("log line missing redacted query %q: %s", want, got)
|
||||
}
|
||||
}
|
||||
for _, want := range tt.preserved {
|
||||
if !strings.Contains(got, want) {
|
||||
t.Fatalf("log line missing preserved query %q: %s", want, got)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user