
एक proof-of-concept lab जो एक critical Lago GraphQL acceptInvite authentication bypass को प्रदर्शित करता है जो unauthenticated invite acceptance के माध्यम से cross-organization account takeover को सक्षम बनाता है।
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · lago-invite-ato
राइट-अप: https://abraxaslabs.tech/research/lago-invite-ato
Lago v1.53.0 - GetLago
Mutations::Invites::Accept में AuthenticableApiUser नहीं है। Create/revoke में है। Accept में नहीं। register_from_invite उपयोगकर्ता को आमंत्रण ईमेल से लोड करता है। यदि उस खाते के पास पहले से सदस्यताएँ हैं, तो पोस्ट किया गया पासवर्ड त्याग दिया जाता है। AuthToken.encode(user:) फिर भी चलता है। JWT उपयोगकर्ता-स्कोप्ड है। कोई org दावा नहीं। क्लाइंट x-lago-organization उस org के लिए भेजता है जिससे वह उपयोगकर्ता पहले से जुड़ा है। पीड़ित के org सहित। createInvite पहले से ही आमंत्रणकर्ता को टोकन लौटाता है।
cfo@victim को एक अस्थायी org में आमंत्रित करें, स्वयं उसे स्वीकार करें, और आप उस व्यक्ति के रूप में हर उस org में हैं जिसमें वह ईमेल पहले से मौजूद है। मेलबॉक्स कभी शामिल नहीं। पीड़ित का पासवर्ड अपरिवर्तित।
| ID | अभी तक कोई CVE नहीं |
| CWE | CWE-287, CWE-306 |
| CVSS | गंभीर: 9.6 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N |
| उत्पाद | Lago / lago-api |
| प्रभावित | v1.53.0 तक ईमेल/पासवर्ड acceptInvite |
| प्रमाणीकरण | org व्यवस्थापक (organization:members:create); Cloud साइनअप पर्याप्त है |
| लाइसेंस | GNU Affero GPL v3.0 |
| लैब | केवल 127.0.0.1 |
आपको एक ऐसा org चाहिए जिसे आप नियंत्रित करते हों। Cloud साइनअप पर्याप्त है (LAGO_DISABLE_SIGNUP डिफ़ॉल्ट रूप से false)। किसी पीड़ित के ईमेल को आमंत्रित करें, डमी पासवर्ड के साथ बिना प्रमाणीकरण के स्वीकार करें, फिर हेडर बदलकर Victim Corp पर जाएँ। इनवॉइस, API कुंजियाँ, Stripe, वॉलेट।
कोई बिना खाते वाला यादृच्छिक आगंतुक नहीं। पासवर्ड रीसेट नहीं। डमी लॉगिन विफल होता है। असली पीड़ित का पासवर्ड अभी भी काम करता है। Google/Okta accept IdP ईमेल को बांधता है और यह इस बग में नहीं आता। सिंगल-org सेल्फ-होस्ट जिसमें DB में किसी और का ईमेल नहीं है, आपको दूसरा व्यापारी नहीं देता। एक ही डेटाबेस, दो org, एक ही ईमेल: यह देता है।
Stripe one-time invoice IDOR के समान ट्री। अलग बग।
मैंने Accept पढ़ा (कोई AuthenticableApiUser नहीं), फिर find_or_initialize_by(email:), फिर वह शाखा जहाँ सदस्यताएँ मौजूद होने पर पासवर्ड छोड़ दिया जाता है, फिर AuthToken.encode(user:)। फिर Google accept, जो वास्तव में google_oidc["email"] == invite.email की जाँच करता है। ईमेल/पासवर्ड accept किसी मौजूदा उपयोगकर्ता के पासवर्ड को नहीं बांधता।
पहला क्लाइंट जो इसे देखेगा, वह किसी अप्रयुक्त पते को आमंत्रित करेगा, उसे स्वीकार करेगा, और उस पासवर्ड के साथ एक बिल्कुल नया Lago उपयोगकर्ता प्राप्त करेगा जो उसने पोस्ट किया था। यही सुविधा है। गवाह यह है कि मौजूदा पीड़ित उपयोगकर्ता id वापस आता है।
पहले से दर्ज गलत रास्ते: Google/Okta के साथ स्वीकार करना; JWT के बिना createInvite 401 को पूरी कहानी मानना (create प्रमाणीकृत है, accept नहीं); currentUser पर केवल हमलावर org को देखना (संकेत Victim Corp सूची में है); डमी पासवर्ड से लॉगिन होना (इसका मतलब होता कि हैश अधिलेखित हो गया - लैब पुष्टि करता है कि ऐसा नहीं हुआ); एक रिवर्स शेल। नाटक। कोई इनबॉक्स नहीं।
फिर: दो registerUser कॉल Victim Corp और Attacker Corp को स्थापित करते हैं। हर रन में नए ईमेल ताकि गंदा वॉल्यूम 422 user_already_exists न दे। विक्टिम ईमेल पर createInvite। डमी पासवर्ड के साथ अनऑथेंटिकेटेड acceptInvite। लौटाया गया यूज़र आईडी विक्टिम से मेल खाता है। currentUser.organizations दोनों को सूचीबद्ध करता है। हेडर स्विच Victim Corp लौटाता है।
cd lab
./run.sh
केवल http://127.0.0.1:13000 को लक्षित करें। Stripe IDOR ने 13001 का उपयोग किया। कोई UI पोर्ट नहीं।
IOC victim_password_unchanged
IOC victim_real_password_still_works
SUCCESS LAGO-INVITE-ATO acceptInvite JWT is existing victim; lists Victim Corp; no inbox
यदि उपयोगकर्ता पहले से मौजूद है, तो सदस्यता जोड़ने से पहले आवश्यक करें कि वे स्वयं के रूप में प्रमाणित करें (या मेलबॉक्स / IdP सिद्ध करें)। अप्रमाणित स्वीकृति से किसी मौजूदा उपयोगकर्ता के लिए JWT न बनाएं। यदि आमंत्रण token एक क्षमता (capability) है, तो उसे आमंत्रणकर्ता को लौटाना बंद करें।
accept.rb · accept_service.rb · users_service.rb · create.rb · object.rb · google_service.rbGNU Affero GPL v3.0। देखें LICENSE। केवल लूपबैक लैब। कोई वारंटी नहीं।