
एक स्थानीय पैकेज स्थापना सहायक ने कॉलर-आपूर्ति पैकेज नामों पर बहुत अधिक भरोसा किया। yeoman-environment में, लापता जनरेटर उपयोगकर्ता की पुष्टि के बिना स्थापित किए जा सकते हैं, जिससे हमलावर-नियंत्रित प्रोजेक्ट मेटाडेटा पैकेज-स्थापना और कोड-निष्पादन पथ में बदल जाता है।
एक स्थानीय पैकेज इंस्टॉलेशन हेल्पर ने कॉलर द्वारा प्रदान किए गए पैकेज नामों पर बहुत अधिक भरोसा किया। yeoman-environment में, लापता जनरेटर उपयोगकर्ता की पुष्टि के बिना स्थापित किए जा सकते थे, जिससे हमलावर-नियंत्रित प्रोजेक्ट मेटाडेटा पैकेज-इंस्टॉल और कोड-निष्पादन पथ में बदल गया।
मुझे यह मुद्दा generator-jhipster की समीक्षा करते समय एक सरल सुरक्षा प्रश्न के साथ मिला:
क्या हमलावर-नियंत्रित प्रोजेक्ट मेटाडेटा एक डेवलपर टूल को तीसरे पक्ष का कोड लाने और निष्पादित करने के लिए मजबूर कर सकता है, इससे पहले कि उपयोगकर्ता स्पष्ट रूप से ऐसा करने के लिए कहे?
इस मामले में, उत्तर हाँ था।
जो शुरू में JHipster मुद्दा लग रहा था, वह yeoman-environment में एक गहरे अपस्ट्रीम मूल कारण के रूप में सामने आया।
कमजोर व्यवहार Yeoman के स्थानीय जनरेटर इंस्टॉलेशन फ्लो में था, जहां कॉलर द्वारा प्रदान किए गए लापता पैकेज उपयोगकर्ता की पुष्टि के बिना स्वचालित रूप से स्थापित हो जाते थे। एक डाउनस्ट्रीम उपभोक्ता में जो हमलावर-नियंत्रित पैकेज नामों को उस पथ में पास करता था, यह एक वास्तविक पैकेज-इंस्टॉलेशन और कोड-निष्पादन श्रृंखला बनाने के लिए पर्याप्त था।
That issue became CVE-2026-42089.
yeoman-environment: GitHub पर yeoman-environment
Package: yeoman-environment (npm)
CVE: CVE-2026-42089
इसने yeoman-environment को प्रभावित किया, जो Yeoman के जनरेटर-लोडिंग और बूटस्ट्रैपिंग फ्लो के पीछे का रनटाइम लेयर है। आधिकारिक प्रोजेक्ट इसे जनरेटर जीवनचक्र और खोज को संभालने वाले घटक के रूप में वर्णित करता है, और 26 जून, 2026 तक, npm पैकेज पेज ने 1,466,426 साप्ताहिक डाउनलोड सूचीबद्ध किए, जो इसे जावास्क्रिप्ट टूलिंग इकोसिस्टम में व्यापक रूप से तैनात पैकेज बनाता है।

attacker-controlled project config -> caller-supplied generator package names -> yeoman-environment silently installs missing packages -> downstream tool loads installed generator code -> package installation and code execution during CLI bootstrap
yeoman-environment Yeoman-आधारित टूलिंग के पीछे का रनटाइम और जनरेटर-लोडिंग लेयर है।
अन्य चीजों के अलावा, यह संभालता है:
इसका मतलब है कि यह सीधे एक विश्वास सीमा पर बैठता है।
प्रासंगिक प्रश्न यह नहीं है कि Yeoman "सिर्फ एक स्थानीय उपकरण" है या नहीं।
प्रासंगिक प्रश्न यह है कि क्या अविश्वसनीय इनपुट पैकेज स्थापना और कोड लोडिंग व्यवहार को प्रभावित कर सकता है।
इस मामले में, यह कर सकता था।
मैं यहां मेमोरी भ्रष्टाचार या केवल क्रैश बग की तलाश में नहीं था।
मजबूत लक्ष्य एक्सटेंशन और पैकेज-समाधान सतह था।
कोई भी सिस्टम जो:
करीबी जांच का हकदार है।
यह विशेष रूप से तब सच है जब डाउनस्ट्रीम उपभोक्ता उन पैकेज नामों को प्रोजेक्ट-स्थानीय डेटा से प्राप्त कर सकता है।
यह बिल्कुल वैसी जगह है जहां सामान्य कॉन्फ़िगरेशन चुपचाप एक सुरक्षा सीमा बन सकता है।
यह देखने के लिए सही जगह थी।
मैंने पहले generator-jhipster के माध्यम से व्यवहार को पुन: उत्पन्न किया।
महत्वपूर्ण पथ था:
.yo-rc.json एक ब्लूप्रिंट पैकेज घोषित करता हैइसका मतलब था कि एक सौम्य कमांड भी जैसे:
jhipster --help
अनुरोधित कमांड पूर्ण होने से पहले पैकेज इंस्टॉलेशन तक पहुँच सकता था।
यह एक वास्तविक विश्वास-सीमा विफलता है।
डाउनस्ट्रीम ट्रिगर ने इसे उजागर करने में मदद की, लेकिन असुरक्षित डिफ़ॉल्ट व्यवहार Yeoman में था।
बग सरल था।
yeoman-environment में, कमजोर विधि थी:
async installLocalGenerators(packages) {
const entries = Object.entries(packages);
const specs = entries.map(([packageName, version]) => `${packageName}${version ? `@${version}` : ''}`);
const installResult = await this.repository.install(specs);
const failToInstall = installResult.find(result => !result.path);
if (failToInstall) {
throw new Error(`Fail to install ${failToInstall.pkgid}`);
}
await this.lookup({ packagePaths: installResult.map(result => result.path) });
return true;
}
वह विधि कॉलर द्वारा प्रदान किए गए पैकेज नामों को सीधे इसके माध्यम से स्थापित करती थी:
this.repository.install(specs)
बिना पहले उपयोगकर्ता से पूछे।
यह मुख्य कमजोरी है।
क्योंकि पैकेज नामों को किसी विश्वसनीय स्रोत से आने की आवश्यकता नहीं है।
यदि कोई डाउनस्ट्रीम उपभोक्ता उन्हें हमलावर-नियंत्रित प्रोजेक्ट मेटाडेटा से प्राप्त करता है, तो शोषण श्रृंखला सीधी है:
यह सिर्फ "पैकेज इंस्टॉल हुआ" नहीं है।
यह अविश्वसनीय इनपुट है जो स्पष्ट सहमति सीमा के बिना पैकेज इंस्टॉलेशन सिंक में पार कर रहा है।
महत्वपूर्ण अंतर अविश्वसनीय इनपुट से मौन स्थापना है।
एक वास्तविक अंतर है:
वह अंतर तब और भी मायने रखता है जब पैकेज तुरंत बाद लोड करने योग्य हो जाता है।
मुद्दा यह नहीं था कि तृतीय-पक्ष जनरेटर मौजूद हैं।
मुद्दा यह था कि Yeoman ने कॉलर द्वारा प्रदान किए गए पैकेज नामों को उपयोगकर्ता की पुष्टि के बिना डिफ़ॉल्ट रूप से स्थापित करने योग्य माना।
यह असुरक्षित डाउनस्ट्रीम विश्वास धारणाओं को काफी खराब बनाता है।
यही कारण है कि फिक्स ने एक पुष्टि गेट जोड़ा।
मैंने दो स्तरों के प्रमाण का उपयोग किया क्योंकि उन्होंने मूल कारण और वास्तविक डाउनस्ट्रीम प्रभाव दोनों का प्रदर्शन किया।
पहला प्रमाण अपरिवर्तित generator-jhipster का उपयोग करता था।
मैंने एक प्रोजेक्ट बनाया जिसमें एक रूट .yo-rc.json था जो एक ब्लूप्रिंट पैकेज को संदर्भित करता था जो पहले से स्थापित नहीं था, फिर चलाया:
jhipster --help
इसके कारण JHipster ने हेल्प पूर्ण होने से पहले लापता ब्लूप्रिंट को Yeoman के स्थानीय जनरेटर इंस्टॉलेशन फ्लो में पास कर दिया।
महत्वपूर्ण परिणाम था:
इसने वास्तविक ट्रिगर स्थिति को स्पष्ट रूप से स्थापित किया।
दूसरे प्रमाण में एक नियंत्रित स्थानीय रजिस्ट्री और एक पैकेज का उपयोग किया गया जो आयात-समय के दुष्प्रभावों को सुरक्षित रूप से प्रदर्शित करने के लिए डिज़ाइन किया गया था।
यह मायने रखता था क्योंकि मैं मजबूत कहानी दिखाना चाहता था:
यह सबसे मजबूत साक्ष्य श्रृंखला थी क्योंकि इसने मुद्दे को आगे बढ़ाया:
"अप्रत्याशित स्थापना प्रयास"
और इसमें:
"इंस्टॉल प्लस डाउनस्ट्रीम कोड-लोडिंग पथ वास्तव में पहुंच योग्य है"
यह वह बिंदु है जहां विश्वास-सीमा विफलता को खारिज करना बहुत कठिन हो जाता है।
पहला PoC मौन स्थापना व्यवहार साबित करता है।
दूसरा PoC साबित करता है कि वह व्यवहार क्यों मायने रखता है।
यह विभाजन महत्वपूर्ण था।
एक रिपोर्ट जो यहीं रुक जाती है:
"एक पैकेज स्थापित किया जा सकता है"
एक ऐसी रिपोर्ट से कमजोर है जो दिखाती है:
यह पूरी कहानी है।
सलाहकार हैंडलिंग और स्थानीय समीक्षा के दौरान, व्यवहार को installLocalGenerators() की शुरूआत में खोजा गया:
yeoman-environment 2.9.0
इसलिए प्रभावित सीमा थी:
>= 2.9.0 and < 6.0.1
निश्चित संस्करण था:
6.0.1
फिक्स सही और न्यूनतम था।
6.0.1 में, installLocalGenerators() को स्थापना से पहले एक पुष्टि चरण जोड़ने के लिए बदल दिया गया, जब तक कि फोर्स-इंस्टॉल स्पष्ट रूप से अनुरोध न किया गया हो।
निश्चित आकार इस तरह दिखता था:
async installLocalGenerators(packages, forceInstall = false) {
और फिर:
const { aproveInstall } = await this.adapter.prompt({
message: `The following packages need to be installed in the local repository: ${specs.join(', ')}. Do you want to proceed?`,
type: 'confirm',
name: 'aproveInstall',
default: false,
});
यदि उपयोगकर्ता मना करता है, तो स्थापना रद्द कर दी जाती है।
यह सही फिक्स है क्योंकि यह लापता विश्वास सीमा को पुनर्स्थापित करता है:
यह फिक्स इसमें उतरा:
78d2af7
के माध्यम से:
PR #753
यह बिल्कुल वैसा ही उपचार है जो आप इस तरह के सुरक्षा मुद्दे में चाहते हैं:
इस मुद्दे को उचित रूप से गंभीरता से लिया गया क्योंकि प्रभाव कॉस्मेटिक या आश्चर्यजनक व्यवहार से अधिक है।
कमजोर व्यवहार निम्नलिखित का कारण बन सकता है:
मुद्दे से संबंधित CVSS वेक्टर था:
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H
यह डाउनस्ट्रीम शोषण कहानी के लिए समझ में आता है:
यह मुद्दा generator-jhipster के खिलाफ एक निजी रिपोर्ट के रूप में शुरू हुआ, क्योंकि यह वास्तविक दुनिया का ट्रिगर पथ था जिसे मैंने शुरू में मान्य किया था।
ट्राइएज के दौरान, JHipster अनुरक्षकों ने बताया कि ऑटो-इंस्टॉल व्यवहार स्वयं yeoman-environment में था और अपस्ट्रीम फिक्स का संदर्भ दिया।
इससे सही पिवट हुआ:
Yeoman अनुरक्षकों ने मुद्दे की समीक्षा की, प्रभावित सीमा की पुष्टि की, और एक निजी सलाह के माध्यम से इसका ट्रैक रखा।
रिपोर्ट को बाद में सौंपा गया:
CVE-2026-42089
उस सलाह में generator-jhipster के माध्यम से वास्तविक डाउनस्ट्रीम ट्रिगर पथ भी दस्तावेज किया गया।
यह एक अच्छा उदाहरण था कि समन्वित प्रकटीकरण को कभी-कभी एक अतिरिक्त कदम की आवश्यकता क्यों होती है:
यहां, डाउनस्ट्रीम पुनरुत्पादन उपयोगी था, लेकिन अपस्ट्रीम पैकेज CVE के लिए सही जगह था।
यहां मुख्य सबक सरल है:
पैकेज स्थापना एक सुरक्षा सीमा है, यहां तक कि स्थानीय डेवलपर टूलिंग में भी
बहुत से लोग सहज रूप से इस तरह के मुद्दों को कम आंकते हैं क्योंकि वे CLI टूल्स में होते हैं।
यह एक गलती है।
वास्तविक प्रश्न यह नहीं है कि उपकरण स्थानीय है या नहीं।
वास्तविक प्रश्न है:
क्या अविश्वसनीय इनपुट उपकरण को स्पष्ट उपयोगकर्ता निर्णय के बिना कोड लाने और विश्वास करने के लिए मजबूर कर सकता है?
इस मामले में, हाँ।
यह वास्तविक निष्कर्ष है।
यह मुद्दा अच्छी कमजोरी अनुसंधान के बारे में कुछ महत्वपूर्ण को भी मजबूत करता है:
यह बिल्कुल इस CVE का आकार था।
यह कमजोरी एक चमकीले पेलोड के बारे में नहीं थी।
यह सही विश्वास-सीमा प्रश्न पूछने के बारे में था।
एक डाउनस्ट्रीम टूल ने प्रोजेक्ट-स्थानीय डेटा को पैकेज चयन को प्रभावित करने दिया। Yeoman ने लापता पैकेज को बिना पुष्टि के स्थापित किया। बाकी कोड-लोडिंग श्रृंखला ने बाकी किया।
यही कारण है कि यह CVE-2026-42089 बन गया।
yeoman-environment 6.0.1 में ठीक किया गया।