GitHub Advisoryadvisory · Go

GHSA-x677-9fxg-v5c5 Traefik: Incomplete fix for CVE-2026-33433 + CVE-2026-39858 cross-cohort: headerField underscore-variant identity spoofing in BasicAuth / DigestAuth / ForwardAuth

HIGH Published 2026-08-06 Modified 2026-08-06 Official page ↗
Aliases
CVE-2026-54763
Ecosystem
Go
Packages
github.com/traefik/traefik/v2, github.com/traefik/traefik/v3
Severity
High
CVSS vector
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:H/SI:H/SA:N
Weaknesses
CWE-178, CWE-290, CWE-345
Reviewed
2026-08-06

Affected packages

• Go github.com/traefik/traefik/v2: < 2.11.51 → fixed in 2.11.51 • Go github.com/traefik/traefik/v3: < 3.6.22 → fixed in 3.6.22 • Go github.com/traefik/traefik/v3: >= 3.7.0, < 3.7.6 → fixed in 3.7.6

Description

Summary There is a high severity vulnerability in Traefik's BasicAuth, DigestAuth, and ForwardAuth middlewares. The fix for CVE-2026-33433 stripped canonical-cased spoofed identity headers (e.g. `X-Auth-User`) before writing Traefik's own value, but did not account for underscore-variant header names (e.g. `X_Auth_User`), which many backends normalize identically to the dashed form. An attacker able to reach a protected route could inject an underscore-variant header that survives Traefik's stripping and reaches the backend alongside — or, on the unauthenticated ForwardAuth `authResponseHeaders` path, instead of — the value Traefik intended to set, spoofing identity or authorization context. This is fixed by setting the new `allowHeadersWithUnderscores: false` entry point option, which strips all headers with underscores in their names before routing. Patches • https://github.com/traefik/traefik/releases/tag/v2.11.51 • https://github.com/traefik/traefik/releases/tag/v3.6.22 • https://github.com/traefik/traefik/releases/tag/v3.7.6 For more information If you have any questions or comments about this advisory, please open an issue. Original Description Incomplete fix for CVE-2026-33433 + CVE-2026-39858 cross-cohort: `headerField` underscore-variant identity spoofing in BasicAuth / DigestAuth / ForwardAuth Summary The fix for CVE-2026-33433 (GHSA-qr99-7898-vr7c, "BasicAuth/DigestAuth Identity Spoofing via Non-Canonical headerField", patched in v2.11.42 / v3.6.12 / v3.7.0-ea.3) added `req.Header.Del(headerField)` before the literal-key writeback in `pkg/middlewares/auth/basic_auth.go` and `pkg/middlewares/auth/digest_auth.go`. Go's `Header.Del` calls `textproto.CanonicalMIMEHeaderKey` which canonicalizes ASCII CASE and treats `-` as a word separator — so the fix correctly strips canonical-cased attacker headers (`X-Auth-User`, `x-auth-user`, `X-AUTH-USER`, etc.). However, `textproto.CanonicalMIMEHeaderKey` does NOT treat `_` as a separator. Attacker-supplied underscore-variant headers such as `X_Auth_User` survive `Header.Del("X-Auth-User")` intact and are forwarded to the backend alongside Traefik's own writeback. Many common backends (CGI/WSGI per RFC 3875, PHP `$_SERVER`, nginx with `underscores_in_headers on`, Tomcat / Java EE servlet containers, ASGI/WSGI frameworks) normalize `_` ↔ `-` equivalently or expose both forms to application code that may read the attacker's value. This is the direct cross-cohort sibling of the threat model the maintainer accepted in CVE-2026-39858 (GHSA-5m6w-wvh7-57vm, "Forwarded alias spoofing pre-auth decision bypass"), which fixed the underscore-variant of the X-Forwarded-* family via `isManagedXHeader` in `pkg/middlewares/forwardedheaders/forwarded_header.go`. The CVE-2026-39858 advisory body states verbatim: > "When the backend normalizes underscore and dash header forms equivalently, an attacker can inject spoofed trust context — such as a trusted scheme or host — through the alias headers and bypass authentication on protected routes without valid credentials." The same threat model applies to the operator-configurable `headerField` (BasicAuth, DigestAuth) and `authResponseHeaders` (ForwardAuth, ingress-nginx snippet provider), but the underscore-handling primitive (`isManagedXHeader`) was not extended to those middlewares. I verified the bypass end-to-end on `traefik:v3.6.14` (the latest patched release containing both fixes) using a default-recommended canonical `headerField: "X-Auth-User"` config and reproduced the bypass with a single `curl -H "X_Auth_User: superadmin" ...` request alongside valid BasicAuth credentials. The defect is present in four code paths at HEAD `eec68dce064f843b4317c4393aaea81b6dea31d6`: 1. `pkg/middlewares/auth/basic_auth.go:101-105` — BasicAuth `headerField` 2. `pkg/middlewares/auth/digest_auth.go:99-103` — DigestAuth `headerField` 3. `pkg/middlewares/auth/forward.go:304-310` — ForwardAuth `authResponseHeaders` per-name writeback 4. `pkg/middlewares/ingressnginx/snippet/snippet.go:480-486` — Ingress-NGINX snippet `authResponseHeaders` per-name writeback The ForwardAuth instance (#3) is particularly notable: the attacker does NOT need credentials. The `authResponseHeaders` mechanism is intended to copy identity headers from the trusted auth server only; the underscore-variant bypass lets an unauthenticated attacker pre-inject the same identity header before any auth happens. The fast proxy at `pkg/proxy/fast/proxy.go:139` explicitly calls `DisableNormalizing()` on the outgoing fasthttp request, guaranteeing that the underscore-variant header reaches the backend wire verbatim. The standard `httputil.ReverseProxy` path at `pkg/proxy/httputil/proxy.go:55` likewise copies `req.Header` keys as-is during the wire write. Affected versions • `traefik` v3.6.x ≤ 3.6.14, v3.7.x ≤ 3.7.0-rc.2, v2.11.x ≤ 2.11.43, and all earlier versions sharing the same auth middleware architecture. The defect is present at HEAD post-CVE-2026-33433 fix (the fix added the `Del` line but the literal-key write defect-class survives for underscore variants). Root cause In `pkg/middlewares/auth/basic_auth.go` at HEAD `eec68dc`: ```go if b.headerField != "" { // TODO Deprecated we should add the header with canonical key. req.Header.Del(b.headerField) req.Header[b.headerField] = []string{user} } ``` The TODO comment shows the maintainer is aware of the literal-key write problem in general (canonical-key write would solve the case-canonicalization issue more cleanly than the current `Del` + literal-write pair). The comment does not acknowledge the underscore-variant survival corollary. `pkg/middlewares/auth/digest_auth.go:99-103` and the two ForwardAuth paths follow the same `Del` + literal-write pattern. Each is independently exploitable; the underlying primitive defect is shared. The maintainer's gold-standard primitive for handling this exact threat class is `pkg/middlewares/forwardedheaders/forwarded_header.go:53-66`: ```go func isManagedXHeader(key string) bool { if len(key) == 0 || key[0] != 'X' { return false } if _, ok := XHeadersSet[key]; ok { return true } if strings.IndexByte(key, '_') /traefik-ht1a-poc; commands below are verbatim. Setup ```yaml docker-compose.yml services: traefik: image: traefik:v3.6.14 command: • --providers.file.filename=/etc/traefik/dynamic.yml • --entrypoints.web.address=:80 ports: • "8080:80" volumes: • ./traefik/dynamic.yml:/etc/traefik/dynamic.yml:ro echo: image: mendhak/http-https-echo:36 environment: • HTTP_PORT=8888 ``` ```yaml traefik/dynamic.yml — canonical headerField, recommended operator config http: routers: protected: rule: "PathPrefix(`/`)" service: echo middlewares: [basic-auth] services: echo: loadBalancer: servers: [{url: "http://echo:8888"}] middlewares: basic-auth: basicAuth: users: • 'alice:$2b$05$FhDfYidZdDPuQjovYqcTAe22wHpQ/cILC7Tr2yAD6vLlvZh/Q45PC' # alice:secret123 headerField: "X-Auth-User" ``` `docker compose up -d`. Test 1 (control — CVE-2026-33433 fix works for canonical case) ```bash $ curl -s -u alice:secret123 -H "X-Auth-User: superadmin" http://localhost:8080/ { ... …

Related

Alias · CVE (1)

  • CVE-2026-54763 Traefik is an HTTP reverse proxy and load balancer. vulnerability

Weakness · CWE (3)

  • CWE-178 Improper Handling of Case Sensitivity weakness
  • CWE-290 Authentication Bypass by Spoofing weakness
  • CWE-345 Insufficient Verification of Data Authenticity weakness

References