CVE-2026-65600: Traefik ReplacePathRegex Authentication Bypass via Path Traversal
A flaw in Traefik's ReplacePathRegex middleware lets an attacker reach password-protected routes with a single crafted request, bypassing BasicAuth, ForwardAuth, or DigestAuth entirely.

The problem
Traefik's ReplacePathRegex middleware rewrites the request path using a user-supplied regex, but never checks whether the resulting path normalizes differently. An attacker can inject dot-segments into the part of the URL captured by the regex, producing a replacement like /../admin that Traefik forwards verbatim.
Because routing and middleware selection already happened against the original path, the request travels through the public router's middleware chain. The backend framework (Express, Flask, Django, Spring, ASP.NET) then normalizes /../admin to /admin and serves the protected resource, no credentials required.
Proof of concept
A working proof-of-concept for CVE-2026-65600 in github.com/traefik/traefik/v2, with the exact payload below.
# Traefik config (dynamic.yml)
# public router: PathPrefix(`/api`), middleware: replacePathRegex ^/api(.*) -> /$1
# protected router: PathPrefix(`/admin`), middleware: basicAuth
# Bypass request (plain)
curl -s http://traefik.host/api../admin
# → 200 ADMIN_SECRET_DATA
# URL-encoded variant
curl -s http://traefik.host/api%2e%2e/admin
# → 200 ADMIN_SECRET_DATA
# The regex ^/api(.*) captures ../admin from the path /api../admin.
# Replacement /$1 produces /../admin, which Traefik forwards without validation.
# The backend normalizes /../admin -> /admin and returns protected content.The root cause is in pkg/middlewares/replacepathregex/replace_path_regex.go (ServeHTTP, lines 56-74). After the regex substitution runs, the middleware sets the new path on req.URL and calls next.ServeHTTP with no further checks. The segment api.. passes Traefik's sanitizePath unchanged because api.. is a valid non-dot segment, so the traversal only materializes after substitution produces /../admin.
The patch (PR #13466, commit 3f10dd4) adds a post-substitution invariant check: it calls req.URL.JoinPath(), which applies RFC 3986 dot-segment removal, and compares the result to req.URL.Path. If they differ, the middleware returns HTTP 400. This is identical to the guard added to StripPrefix when CVE-2026-48020 was fixed.
The exploitable pattern is any regex that omits a mandatory / separator before the capture group, e.g., ^/api(.*) rather than ^/api/(.*).
The fix
Upgrade to Traefik v2.11.52, v3.6.23, or v3.7.7. If an immediate upgrade is not possible, change any ReplacePathRegex pattern from ^/api(.*) to ^/api/(.*) (add a mandatory slash before the capture group) to prevent traversal sequences from entering the captured segment.
Alternatively, place a WAF rule upstream that rejects requests containing .. or percent-encoded dot sequences (%2e%2e, %2E%2E) in the path.
Reported by rtribotte (Traefik maintainer, advisory author).
Related research
- highCVE-2026-54763CVE-2026-54763: Traefik BasicAuth/DigestAuth/ForwardAuth Underscore Header Identity Spoofing
- highCVE-2026-71324CVE-2026-71324: Traefik HTTP/2 CONNECT Pool Poisoning Cross-User Response Smuggling
- highCVE-2026-67309CVE-2026-67309: Traefik Kubernetes Ingress NGINX RewriteTarget Path Traversal Authentication Bypass
- high · 8.8CVE-2026-59733CVE-2026-59733: rclone serve restic --private-repos Authorization Bypass via Path Traversal