mirror of
https://github.com/lukaszraczylo/traefikoidc.git
synced 2026-10-18 04:47:28 +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:
@@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/url"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -33,6 +34,16 @@ func (t *TraefikOidc) determineExcludedURL(currentRequest string) bool {
|
||||
// an unrelated sibling such as "/publicsecret", so a configured exclusion can no
|
||||
// longer be widened into an authentication bypass on a different resource.
|
||||
func pathExcluded(requestPath, excluded string) bool {
|
||||
// Normalize dot segments and redundant slashes so an exclusion cannot be
|
||||
// escaped by traversal. Go's server leaves ".." in req.URL.Path (verified:
|
||||
// url.ParseRequestURI keeps dot segments), so "/public/../admin" would match
|
||||
// an "/public" exclusion even though the real resource is "/admin". path.Clean
|
||||
// resolves this to "/admin" before the boundary check. "." (empty or bare)
|
||||
// maps back to "" preserving the original root-match semantics.
|
||||
requestPath = path.Clean(requestPath)
|
||||
if requestPath == "." {
|
||||
requestPath = ""
|
||||
}
|
||||
excluded = strings.TrimRight(excluded, "/")
|
||||
if excluded == "" {
|
||||
// A "/" (root) exclusion only matches the root path, not everything.
|
||||
|
||||
Reference in New Issue
Block a user