GitHub Security Advisory: GHSA-6384-m2mw-rf54
Package: github.com/traefik/traefik/v3 (GO)
Severity: HIGH (CVSS 10.0)
CWE: CWE-345: Insufficient Verification of Data Authenticity
Vulnerable versions: >= 3.7.0-ea.1, < 3.7.0-rc.2
Patched in: 3.7.0-rc.2

Summary: Traefik's ForwardAuth trustForwardHeader=false allows spoofed X-Forwarded-Prefix to bypass authentication

Details:
## Summary

There is a high-severity authentication bypass vulnerability in Traefik's `ForwardAuth` middleware when `trustForwardHeader=false` is configured and Traefik is deployed behind a trusted upstream proxy.

While `X-Forwarded-*` headers (such as `X-Forwarded-For`, `X-Forwarded-Host`, and `X-Forwarded-Proto`) from trusted context are correctly rebuilt, it does not strip or rebuild `X-Forwarded-Prefix`, leaving any attacker-supplied value intact in the subrequest forwarded to the authentication service.

When the authentication service makes authorization decisions based on `X-Forwarded-Prefix`, an external attacker can spoof a trusted prefix value and gain unauthorized access to protected backend routes.

## Patches

- https://github.com/traefik/traefik/releases/tag/v2.11.43
- https://github.com/traefik/traefik/releases/tag/v3.6.14
- https://github.com/traefik/traefik/releases/tag/v3.7.0-rc.2

## For more information

If there are any questions or comments about this advisory, please [open an issue](https://github.com/traefik/traefik/issues).

<details>
<summary>Original Description</summary>

### Summary
`ForwardAuth` with `trustForwardHeader=false` still forwards an attacker-controlled `X-Forwarded-Prefix` header to the authentication service when Traefik is deployed behind a trusted upstream proxy. If the auth service relies on `X-Forwarded-Prefix` for authorization or routing decisions, an external attacker can bypass access controls and reach protected backend routes.

This was validated this against Traefik `v3.6.12` using the official Docker image and a minimal local Docker setup. A direct request to Traefik is correctly rejected, but the same request succeeds when sent through a trusted reverse proxy, which shows the issue is in the `ForwardAuth` subrequest handling rather than general ingress header stripping.

### Details
The vulnerable behavior comes from the way Traefik builds the subrequest sent to the forward-auth server.

In [`pkg/middlewares/auth/forward.go`](pkg/middlewares/auth/forward.go), `writeHeader` first copies all incoming request headers into the auth subrequest:

```go
func writeHeader(req, forwardReq *http.Request, trustForwardHeader bool, allowedHeaders []string) {
    utils.CopyHeaders(forwardReq.Header, req.Header)
    ...
    forwardReq.Header = filterForwardRequestHeaders(forwardReq.Header, allowedHeaders)
```

It then selectively rebuilds only a subset of forwarded headers when `trustForwardHeader=false`, for example:

- `X-Forwarded-For`
- `X-Forwarded-Method`
- `X-Forwarded-Proto`
- `X-Forwarded-Port`
- `X-Forwarded-Host`
- `X-Forwarded-Uri`

However, it does **not** remove or rebuild `X-Forwarded-Prefix`, so an attacker-supplied value remains in the auth request even when forwarded headers are supposed to be untrusted.

This becomes security-relevant when `StripPrefix` is used before `ForwardAuth`. In [`pkg/middlewares/stripprefix/strip_prefix.go`](pkg/middlewares/stripprefix/strip_prefix.go), Traefik a