From 68065df1401cd533bce450668c9fda0df8f464c0 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 12 Feb 2026 20:29:09 +0000 Subject: [PATCH] fix(security): move Gemini API key from URL query params to header (#47) Pass the API key via x-goog-api-key HTTP header instead of the URL query parameter to prevent credential leakage in proxy logs, web server access logs, and monitoring systems. Resolves: #47 (CVSS 5.3, OWASP A09:2021) Co-Authored-By: Claude Opus 4.6 --- pkg/ratelimit/ratelimit.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/pkg/ratelimit/ratelimit.go b/pkg/ratelimit/ratelimit.go index c02adab1..bb51d49a 100644 --- a/pkg/ratelimit/ratelimit.go +++ b/pkg/ratelimit/ratelimit.go @@ -343,7 +343,7 @@ func (rl *RateLimiter) AllStats() map[string]ModelStats { // CountTokens calls the Google API to count tokens for a prompt. func CountTokens(apiKey, model, text string) (int, error) { - url := fmt.Sprintf("https://generativelanguage.googleapis.com/v1beta/models/%s:countTokens?key=%s", model, apiKey) + url := fmt.Sprintf("https://generativelanguage.googleapis.com/v1beta/models/%s:countTokens", model) reqBody := map[string]any{ "contents": []any{ @@ -360,7 +360,14 @@ func CountTokens(apiKey, model, text string) (int, error) { return 0, err } - resp, err := http.Post(url, "application/json", bytes.NewBuffer(jsonBody)) + req, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(jsonBody)) + if err != nil { + return 0, err + } + req.Header.Set("Content-Type", "application/json") + req.Header.Set("x-goog-api-key", apiKey) + + resp, err := http.DefaultClient.Do(req) if err != nil { return 0, err }