
CVE-2026-93355 का सुरक्षित, ऑफ़लाइन पुनरुत्पादन — LiteLLM अनसत्यापित-ईमेल JWT खाता अधिग्रहण (LiteLLM के वास्तविक कोड को चलाता है)
एक स्व-निहित, डिस्पोज़ेबल लैब जो
CVE-2026-93355 को पुनः उत्पन्न करती है: LiteLLM का
JWT प्रमाणीकरण कॉलर की पहचान को ईमेल मिलान पर फ़ॉलबैक करके हल करता है — और कभी भी email_verified दावे की जाँच नहीं करता। एक हमलावर जो अपने स्वयं के पहचान-प्रदाता खाते से वैध रूप से हस्ताक्षरित टोकन जारी करवा सकता है जिसमें पीड़ित का ईमेल पता (असत्यापित) हो, वह पीड़ित की भूमिका प्राप्त कर लेता है, जो proxy_admin तक हो सकती है, और यह मिलान चुपचाप पीड़ित के संग्रहीत SSO बाइंडिंग को हमलावर के विषय (subject) पर फिर से लिख देता है, जिससे अधिग्रहण स्थायी हो जाता है।
| सलाह | VulnCheck · OX Security |
| CVE | CVE-2026-93355 |
| प्रोजेक्ट | litellm (प्रॉक्सी / JWT प्रमाणीकरण) |
| प्रभावित | सलाह के अनुसार ≤ 1.102.1 — अभी भी अनपैच्ड: 2026-10-07 तक 1.104.0 (नवीनतम स्थिर) और main में कमज़ोर कोड अपरिवर्तित है |
| CVSS | 8.1 HIGH (AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N) |
| कमज़ोरी | CWE-1390 — कमज़ोर प्रमाणीकरण |
| मूल कारण | email_verified सत्यापित किए बिना ईमेल-आधारित उपयोगकर्ता लुकअप पर भरोसा |
| खोज | Nir Zadok और Moshe Siman Tov Bustan (OX Security) |
फ़िक्स स्थिति (2026-10-07): अभी तक कोई फ़िक्स्ड रिलीज़ मौजूद नहीं है। सलाह में
1.102.1केवल इसलिए सूचीबद्ध है क्योंकि प्रकटीकरण के समय यह नवीनतम संस्करण था; LiteLLM ने तब से1.103.xऔर1.104.0जारी किए हैं, और दोनों में — तथाmainपर भी —_get_fuzzy_user_objectमें अभी भी कोईemail_verifiedजाँच नहीं है। लैब पुनरुत्पादनशीलता के लिए1.102.1को पिन करती है;scripts/verify_against_real_source.pyउस दिन को चिह्नित करेगा जब कोई फ़िक्स आएगा।
यह शैक्षिक और रक्षात्मक उद्देश्यों के लिए एक सार्वजनिक रूप से प्रकट की गई कमज़ोरी को पुनः उत्पन्न करता है। यह पूरी तरह से स्थानीय रूप से चलता है और किसी वास्तविक सेवा को स्पर्श नहीं करता:
[email protected]
एडमिन पंक्ति को हल करता है और उसे प्रिंट करता है। कोई वास्तविक खाता नहीं, कोई वास्तविक
कुंजी नहीं, और कुछ भी आपकी मशीन से बाहर नहीं जाता।LiteLLM का प्रॉक्सी आपको अपने कॉन्फ़िगर किए गए पहचान प्रदाता से JWT के साथ प्रमाणित करने देता है। उस टोकन को LiteLLM उपयोगकर्ता से मैप करने के लिए यह get_user_object() को कॉल करता है, जो टोकन के विषय (sso_user_id) को आज़माता है और, मिस होने पर, _get_fuzzy_user_object() पर फ़ॉलबैक करता है — जो email दावे पर केस-असंवेदनशील मिलान है। LiteLLM की तालिका में उस ईमेल का स्वामी जो भी है, आप वही बन जाते हैं। टोकन के email_verified दावे को कभी नहीं पढ़ा जाता — न दावा निष्कर्षण (JWTHandler.get_user_email) के दौरान और न ही समाधान के दौरान। इसलिए कोई भी IdP जो असत्यापित ईमेल के लिए टोकन जारी करेगा (अधिकांश करेंगे, डिज़ाइन से — सत्यापन तो निर्भर पक्ष का काम है) एक हमलावर को अपनी प्रोफ़ाइल ईमेल को पीड़ित के ईमेल पर सेट करने, टोकन प्रस्तुत करने, और पीड़ित की भूमिका प्राप्त करने देता है। इससे भी बदतर, ईमेल मिलान पर LiteLLM एक पृष्ठभूमि कार्य चलाता है जो पीड़ित के sso_user_id को हमलावर के विषय से अधिलेखित कर देता है — इसलिए हर बाद का लॉगिन सीधे पीड़ित के खाते पर हल हो जाता है बिना किसी ईमेल की आवश्यकता के, और ईमेल बदलने से भी मदद नहीं मिलती।

परीक्षण के अंतर्गत सब कुछ LiteLLM का अपना कोड है, जो पिन किए गए
litellm==1.102.1 पैकेज से आयातित है। लैब केवल दो चीज़ें प्रदान करती है जो उसे अवश्य चाहिए: एक नकली
इन-मेमोरी उपयोगकर्ता तालिका और एक मॉक IdP कीपेयर। यह कमज़ोर तर्क को पुनः कार्यान्वित नहीं करती।
_get_fuzzy_user_object और JWTHandler.get_user_email पर inspect.getsource() चलाते हैं और जाँचते हैं कि ईमेल फ़ॉलबैक मौजूद है, sso_user_id रीबाइंड मौजूद है, और इनमें से कोई भी फ़ंक्शन email_verified का संदर्भ नहीं देता है। → scripts/verify_against_real_source.py_get_fuzzy_user_object के माध्यम से चलाया जाता है; यह विक्टिम की proxy_admin पंक्ति पर रिज़ॉल्व होता है। → poc/01_account_takeover.pysso_user_id को हमलावर के सब्जेक्ट से रीबाइंड कर देता है; बाद में बिना किसी ईमेल के लॉगिन सीधे एडमिन पर रिज़ॉल्व होता है, और "डुप्लिकेट ईमेल ठीक करना" इसे रद्द नहीं करता। → poc/02_persistent_rebind.pyemail_verified को लागू करना हमले को रोकता है जबकि सत्यापित SSO लॉगिन काम करते रहते हैं। → poc/03_patched_path.py./run.sh
run.sh एक अस्थायी .venv बनाता है, litellm[proxy]==1.102.1 इंस्टॉल करता है, ग्राउंड-ट्रुथ जाँच चलाता है, और फिर तीनों PoC चलाता है। पहली बार चलाने पर LiteLLM डाउनलोड होता है और कुछ मिनट लगते हैं; साफ़ करने के लिए .venv हटा दें। किसी मौजूदा इंटरप्रेटर का उपयोग करने के लिए:
PYTHON=python3.12 ./run.sh।
एकल PoC को सीधे चलाएँ (venv के अंदर):
.venv/bin/python poc/01_account_takeover.py
cve-2026-93355-lab/
├── mock_idp.py # ephemeral RS256 OIDC IdP (real signatures)
├── fake_litellm_db.py # in-memory stand-in for the Prisma user table
├── harness.py # configures & drives LiteLLM's real objects
├── poc/
│ ├── 01_account_takeover.py # unverified email -> victim's proxy_admin
│ ├── 02_persistent_rebind.py # sso_user_id overwrite -> persistent access
│ └── 03_patched_path.py # the email_verified guard that closes it
├── scripts/
│ └── verify_against_real_source.py # proves the PoCs run the real vulnerable code
├── assets/attack-flow.svg|.png # the diagram above
├── blog-cve-2026-93355.md # the guard0 write-up
└── run.sh
email_verified: true लागू करें; असत्यापित ईमेल को अस्वीकार या अनदेखा करें।user_id_jwt_field) से बाँधें, न कि किसी परिवर्तनशील ईमेल से, और ईमेल fallback को चुपचाप इसे पुनःबाइंड करने न दें।proxy_admin पंक्ति एक स्थायी takeover primitive है।