mirror of
https://github.com/lukaszraczylo/traefik-llmgateway.git
synced 2026-10-21 05:57:53 +00:00
fix(security): harden retry, SSE, Redis and cost-budget paths
The gateway refuses a request for an unpriced model when the caller has a cost budget. An unpriced model cost 0, so the budget counter was never written and the budget could never fire. The new allowUnpricedWithCostBudget setting restores the old behaviour. The retry loop honours an upstream Retry-After of up to 30s and jitters its own computed backoff. SSE parsing bounds the total size of one event. The Redis client can use TLS. Provider base URLs and errors are scrubbed of credentials before they reach logs or the admin view. The gateway warns when failover and retry settings multiply into a large number of outbound calls. Claude-Session: https://claude.ai/code/session_01V5jYJNxpDFdJkyyExpADrv
This commit is contained in:
+7
-12
@@ -5,8 +5,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
@@ -208,17 +206,14 @@ func (t *targetHealthTracker) record(kind, name, rawURL string, ok bool, err err
|
||||
// carries a password — builds net/http's exact masked form itself
|
||||
// (mirroring stripPassword's own strings.Replace call precisely) and
|
||||
// scrubs against that too.
|
||||
// (Security audit run-1, finding F-2): the URL-aware second pass this
|
||||
// function used to carry privately now lives in sanitizeProviderErr
|
||||
// (admin.go), so the target path and the provider path share ONE
|
||||
// implementation. That private copy is precisely why the provider path
|
||||
// went unprotected — this delegation is what stops the two diverging
|
||||
// again.
|
||||
func sanitizeTargetErr(msg, rawURL string) string {
|
||||
msg = sanitizeProviderErr(msg, rawURL)
|
||||
u, parseErr := url.Parse(rawURL)
|
||||
if parseErr != nil || u.User == nil {
|
||||
return msg
|
||||
}
|
||||
if _, hasPassword := u.User.Password(); !hasPassword {
|
||||
return msg
|
||||
}
|
||||
masked := strings.Replace(u.String(), u.User.String()+"@", u.User.Username()+":***@", 1)
|
||||
return sanitizeProviderErr(msg, masked)
|
||||
return sanitizeProviderErr(msg, rawURL)
|
||||
}
|
||||
|
||||
// stateOf reports (kind, name)'s current targetHealthState — see this
|
||||
|
||||
Reference in New Issue
Block a user