highCVE-2026-88004Sep 10, 2026

CVE-2026-88004: Traefik Entrypoint Header Sanitization Bypass via HTTP Trailers

Rohit Hatagale
AI Security Researcher, SecureLayer7

Traefik's defenses against spoofed trusted header names only scan HTTP headers, not trailers, so an attacker can smuggle a banned name like X_Auth_User or X-Forwarded-Prefix as a chunked trailer and…

Packagegithub.com/traefik/traefik/v3
Ecosystemgo
Affected>= 3.2.0, < 3.7.13
Fixed in3.7.13
CVE-2026-88004: Traefik Entrypoint Header Sanitization Bypass via HTTP Trailers

The problem

Traefik v3's entrypoint handlers (aliasHeadersStrategy, underscoreHeadersStrategy, forwardedHeaders) iterate req.Header but never req.Trailer. An unauthenticated client can declare a sanitized or trusted header name as a chunked HTTP/1.1 trailer or an HTTP/2 trailer: reject mode skips its 400, delete mode skips the removal, and X-Forwarded-* stripping is bypassed entirely.

On bare proxy paths only the trailer name reaches the backend (no value). When a body-buffering middleware is in the chain, such as the retry middleware with status codes or the buffering middleware, the trailer value is also populated before the proxy clone, giving the attacker full control over the value.

Backends that merge trailers into their header namespace then act on the injected name and value.

Proof of concept

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

http
POST / HTTP/1.1
Host: 127.0.0.1:8090
Connection: close
Transfer-Encoding: chunked
Trailer: X_Auth_User

5
hello
0
X_Auth_User: attacker-value

The root cause is a scan gap: removeAliasingHeaders, rejectAliasingHeaders, removeHeadersWithUnderscores, rejectHeadersWithUnderscores, and forwardedheaders.DeleteXForwardedHeaders all loop over req.Header only. Go's HTTP server pre-fills declared trailer keys into req.Trailer with nil values before the handler runs, so the names are invisible to those loops.

On body-buffering chains (retry with status, or the buffering middleware), the body is drained before http.Request.Clone, which populates the trailer values, and the clone carries them to the backend. This is CWE-116 (Interpretation Conflict) and CWE-807 (Reliance on Untrusted Inputs in a Security Decision).

The fix in PR #13822 stops forwarding trailer values to the backend entirely. Declared trailer names are still forwarded as a hint (RFC 9110 §6.6.2), but with nil values, so trailer-merging backends cannot act on attacker-supplied data.

The fix

Upgrade to Traefik v3.7.13. The fix (commit 55bbda4f, PR #13822) makes the httputil reverse proxy clear all request trailer values before forwarding, so no attacker-controlled value can reach the backend regardless of middleware chain. Traefik v2 is not affected.

EOL v3.2 through v3.6 lines will not receive a backport; upgrade to v3.7.13.

Reporter not attributed.

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

Related research