highCVE-2026-67309Aug 6, 2026

CVE-2026-67309: Traefik Kubernetes Ingress NGINX RewriteTarget Path Traversal Authentication Bypass

Shubham Kandhare
Security Engagement Manager, SecureLayer7

A path traversal flaw in Traefik's Kubernetes Ingress NGINX provider lets an unauthenticated attacker reach protected routes by sending a single crafted HTTP request that bypasses route-level…

Packagegithub.com/traefik/traefik/v3
Ecosystemgo
Affected>= 3.7.0, <= 3.7.7
Fixed in3.7.8
CVE-2026-67309: Traefik Kubernetes Ingress NGINX RewriteTarget Path Traversal Authentication Bypass

The problem

Traefik v3.7.0 through v3.7.7 introduced a Kubernetes Ingress NGINX provider that translates nginx.ingress.kubernetes.io/rewrite-target annotations into an internal RewriteTarget middleware. When an Ingress path regex captures attacker-controlled text without requiring a path separator, for example /api(.*) with replacement /$1, the middleware rewrites the path after router selection has already happened.

A request to /api../admin passes the entry-point sanitizer untouched because api.. is a single ordinary segment. The public router matches it, RewriteTarget captures ../admin and produces /../admin, then forwards that path to the backend with no normalization check.

Any backend that resolves dot segments internally sees /admin and returns protected content, bypassing whatever BasicAuth, DigestAuth, or ForwardAuth was attached to the /admin router.

Proof of concept

A working proof-of-concept for CVE-2026-67309 in github.com/traefik/traefik/v3, with the exact payload below.

bash
# Confirm auth is enforced normally
curl --path-as-is -i http://127.0.0.1:18080/admin
# -> HTTP/1.1 401 Unauthorized

# Exploit: dot-segment traversal via rewrite
curl --path-as-is -i http://127.0.0.1:18080/api../admin
# -> HTTP/1.1 200 OK
# -> {"rawPath":"/../admin","normalizedPath":"/admin","result":"ADMIN_SECRET_DATA"}

# Percent-encoded variant also works
curl --path-as-is -i http://127.0.0.1:18080/api%2e%2e/admin
# -> HTTP/1.1 200 OK
# -> {"rawPath":"/../admin","normalizedPath":"/admin","result":"ADMIN_SECRET_DATA"}

The root cause is a missing post-rewrite normalization invariant in pkg/middlewares/ingressnginx/rewritetarget/rewrite_target.go. After calling rt.regexp.ReplaceAllString, the middleware assigned the result directly to req.URL.RawPath and forwarded the request without checking whether url.PathUnescape of that value equals its normalized form.

The sibling ReplacePathRegex middleware received an identical fix earlier (GHSA-cxjq-mrr5-89rv) via req.URL.JoinPath() followed by an HTTP 400 rejection when normalization changes the path. The v3.7.8 patch commit (759515bec1b9f628b21ea8968ef63da853be5e29) applied the same invariant check to RewriteTarget, closing the drift.

Entry-point sanitizePath=true is not a mitigation because sanitization runs before routing and before RewriteTarget constructs the traversal sequence.

The fix

Upgrade to Traefik v3.7.8. As a temporary workaround, change the Ingress path regex to require a separator or end-of-path before any captured user data, for example use path /api(/|$)(.*) with rewrite-target: /$2 instead of /api(.*) with /$1. Also enforce authentication at the backend layer rather than relying solely on Traefik router-level middleware.

Versions v2.11 and v3.6 do not contain the ingress-nginx RewriteTarget implementation and are not affected.

Reported by kevinpollet (Traefik maintainer, advisory publisher).

References: [1][2][3][4][5]

Related research