mirror of
https://github.com/lukaszraczylo/traefikoidc.git
synced 2026-10-12 04:04:26 +00:00
R89: normalize excluded-url paths; apply defaults to pooled HTTP clients
Two verified defects from R89 scout round:
1. Excluded-URL dot-segment traversal widening (P1, auth bypass).
shouldBypassAuth passes req.URL.Path raw (middleware.go:54); Go's server
leaves '..' in URL.Path (url.ParseRequestURI does not normalize), so an
exclusion for /public also matched /public/../admin, letting a real
sibling (/admin) reach the backend unauthenticated. pathExcluded now
path.Clean()s the request path ('.' -> '' to preserve root semantics)
before boundary matching. Regression TestR89ExcludedPathDotTraversal
fails on old (all 4 traversal cases wrongly excluded), passes on new.
2. Pooled HTTP client had no zero-value defaults (P2, unbounded stall).
CreateHTTPClient applies defaults; CreatePooledHTTPClient and
GetOrCreateTransport did not, so a partial config yielded Timeout=0 and
ResponseHeaderTimeout=0 (a hanging upstream stalls forever). Extracted
applyHTTPClientDefaults (single source of truth) and applied it in all
three construction paths; pool cache key now reflects normalized values.
Regression TestR89PooledClientAppliesDefaults fails on old, passes on new.
R89 clean/declined: session max-age IS absolute-and-enforced-every-request
(verified, review_r68 already locks it); AllowedUserDomains fail-closed (P2
'*' not a wildcard, P3 TrimSpace — declined as config-scoped).
This commit is contained in:
+14
-4
@@ -138,10 +138,13 @@ func (f *HTTPClientFactory) ValidateHTTPClientConfig(config *HTTPClientConfig) e
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateHTTPClient creates an HTTP client with the given configuration
|
||||
// Validates configuration parameters before creating the client
|
||||
func (f *HTTPClientFactory) CreateHTTPClient(config HTTPClientConfig) *http.Client {
|
||||
// Set defaults for zero values before validation
|
||||
// applyHTTPClientDefaults fills zero-valued fields in cfg with the standard
|
||||
// conservative defaults so that a partially-populated config never yields an
|
||||
// unbounded HTTP client (zero overall Timeout or ResponseHeaderTimeout would make
|
||||
// a stalled upstream hang forever). All construction paths MUST converge on this
|
||||
// helper so behavior is identical: CreateHTTPClient and the shared transport
|
||||
// pool (CreatePooledHTTPClient / GetOrCreateTransport).
|
||||
func applyHTTPClientDefaults(config *HTTPClientConfig) {
|
||||
if config.Timeout == 0 {
|
||||
config.Timeout = 30 * time.Second
|
||||
}
|
||||
@@ -178,6 +181,13 @@ func (f *HTTPClientFactory) CreateHTTPClient(config HTTPClientConfig) *http.Clie
|
||||
if config.ReadBufferSize == 0 {
|
||||
config.ReadBufferSize = 4096
|
||||
}
|
||||
}
|
||||
|
||||
// CreateHTTPClient creates an HTTP client with the given configuration
|
||||
// Validates configuration parameters before creating the client
|
||||
func (f *HTTPClientFactory) CreateHTTPClient(config HTTPClientConfig) *http.Client {
|
||||
// Set defaults for zero values before validation
|
||||
applyHTTPClientDefaults(&config)
|
||||
|
||||
// Validate configuration - only fail on critical errors
|
||||
if err := f.ValidateHTTPClientConfig(&config); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user