CVE-2026-54763: Traefik BasicAuth/DigestAuth/ForwardAuth Underscore Header Identity Spoofing
Attackers can inject an underscore-variant HTTP header (e.g. X_Auth_User) that bypasses Traefik's identity-header stripping and reaches the backend with a spoofed user value, defeating BasicAuth…

The problem
Traefik's BasicAuth and DigestAuth middlewares call req.Header.Del(headerField) before writing the authenticated username. Go's textproto.CanonicalMIMEHeaderKey normalises ASCII case and treats - as a word separator, but it does NOT treat _ as a separator.
So Del("X-Auth-User") leaves an attacker-supplied X_Auth_User header completely untouched.
The surviving header is then forwarded to the backend alongside Traefik's own writeback. Backends that normalise _ and - equivalently (CGI/WSGI per RFC 3875, PHP $_SERVER, nginx with underscores_in_headers on, Tomcat, ASGI frameworks) will merge or prefer the attacker's value.
The ForwardAuth authResponseHeaders path is worse: the attacker does not need credentials at all, because the underscore header is injected before authentication runs.
Proof of concept
A working proof-of-concept for CVE-2026-54763 in github.com/traefik/traefik/v2, with the exact payload below.
# BasicAuth bypass: valid credentials + underscore-variant spoof header
# Backend receives both x-auth-user: alice (Traefik) AND x_auth_user: superadmin (attacker)
curl -s -u alice:secret123 \
-H 'X_Auth_User: superadmin' \
http://traefik-host/protected
# Double-send (canonical stripped, underscore survives)
curl -s -u alice:secret123 \
-H 'X-Auth-User: superadmin' \
-H 'X_Auth_User: superadmin' \
http://traefik-host/protected
# ForwardAuth path: NO credentials needed
curl -s \
-H 'X_Auth_User: superadmin' \
http://traefik-host/forward-auth-protectedThe root cause is the incomplete fix from CVE-2026-33433. That fix added req.Header.Del(b.headerField) in pkg/middlewares/auth/basic_auth.go and digest_auth.go, but Go's Del canonicalises via textproto.CanonicalMIMEHeaderKey, which maps - to a word-boundary marker and normalises case, but treats _ as a regular letter.
A key like X_Auth_User therefore has a different canonical form from X-Auth-User and survives the Del call untouched.
The same gap exists in pkg/middlewares/auth/forward.go and pkg/middlewares/ingressnginx/snippet/snippet.go for the authResponseHeaders per-name writeback. Traefik's fast proxy (pkg/proxy/fast/proxy.go) explicitly calls DisableNormalizing() on the outgoing fasthttp request, guaranteeing the underscore header reaches the backend wire verbatim.
The patch introduces a new allowHeadersWithUnderscores: false entry-point option (PR #13262, commit 108a5264) that strips all headers containing underscores at the entry point, before any middleware executes.
The fix
Upgrade to Traefik v2.11.51, v3.6.22, or v3.7.6. After upgrading, set allowHeadersWithUnderscores: false on every entry point that fronts a route protected by BasicAuth, DigestAuth, or ForwardAuth. This option, added in PR #13262, strips all underscore-name headers at ingress before middleware processing begins.
Without explicitly setting this option the upgrade alone does not close the bypass.
Reported by Matteo Panzeri.
Related research
- critical · 9.1CVE-2026-65600CVE-2026-65600: Traefik ReplacePathRegex Authentication Bypass via Path Traversal
- highCVE-2026-71324CVE-2026-71324: Traefik HTTP/2 CONNECT Pool Poisoning Cross-User Response Smuggling
- high · 8.3CVE-2026-54174CVE-2026-54174: apko Incomplete APK Data Section Integrity Verification
- critical · 9.1CVE-2026-54089CVE-2026-54089: File Browser Authentication Bypass via Proxy Header Forgery