
अमान्य customBasePath के माध्यम से datamodel-code-generator में कोड इंजेक्शन (RCE) (CVE-2026-63720)
गंभीरता: उच्च, CVSS 3.1 7.5 / CVSS 4.0 7.5 (VulnCheck, CNA द्वारा निर्धारित)
पर्यावरणीय सीमा (नेटवर्क-सेवा तैनाती): 9.8 तक
वेक्टर (v4.0): CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:A/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
वेक्टर (v3.1): CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H
प्रभावित: datamodel-code-generator < 0.70.0
इसमें ठीक हुआ: 0.70.0
CWE: CWE-94 (कोड निर्माण का अनुचित नियंत्रण, 'कोड इंजेक्शन')
रिपोर्टकर्ता: Rahul Karne
CNA: VulnCheck
प्रकाशित: 26 जुलाई, 2026
datamodel-code-generator ने कोड-इंजेक्शन पेलोड ले जाने वाली हर स्कीमा-नियंत्रित इम्पोर्ट स्ट्रिंग को मान्य किया, एक को छोड़कर।
यह टूल इनपुट स्कीमा (JSON Schema, OpenAPI, YAML) को Python मॉडल सोर्स में बदलता है। कई स्कीमा फ़ील्ड सीधे उस जनरेटेड कोड में प्रस्तुत की जाती हैं, इसलिए प्रोजेक्ट उन्हें उपयोग से पहले डॉटेड Python आइडेंटिफ़ायर के रूप में मान्य करता है, विशेष रूप से इंजेक्शन रोकने के लिए। स्कीमा एक्सटेंशन फ़ील्ड customBasePath एकमात्र ऐसा सहोदर फ़ील्ड है जो इस जाँच को छोड़ देता है। इसका मान बिना सैनिटाइज़ किए जनरेटेड आउटपुट में from ... import ... स्टेटमेंट में पहुँचता है। जो हमलावर इनपुट स्कीमा को नियंत्रित करता है, वह न्यूलाइन और डॉट-रहित एक्सप्रेशन का उपयोग करके मनमाना Python एम्बेड कर सकता है, और जनरेटेड मॉड्यूल इम्पोर्ट होते ही यह निष्पादित हो जाता है, जो मॉडल जनरेट करने के बाद का सामान्य अगला कदम है।
यह CVE-2026-55415 (GHSA-5578-w22f-pfx9) का अधूरा सुधार है, जिसने सहोदर फ़ील्ड customTypePath और x-python-import को इसी श्रेणी के हमले से सुरक्षित किया था। उस सुधार ने customBasePath को कवर नहीं किया, जो बिना मान्य किए उसी सिंक तक पहुँचता है और 0.68.1 तथा 0.70.0 तक main ब्रांच में शोषण योग्य बना रहा।
जनरेटेड मॉडल को इम्पोर्ट या चलाने वाली प्रक्रिया में मनमाना Python कोड निष्पादन: डेवलपर की मशीन, CI रनर, या कोई भी सेवा जो मॉडल जनरेट करती है और फिर लोड करती है। होस्ट की गोपनीयता, अखंडता और उपलब्धता पूरी तरह से समझौता हो जाती है, केवल उस प्रक्रिया के विशेषाधिकारों द्वारा सीमित।
गंभीरता पूरी तरह से इस बात पर निर्भर करती है कि कोडजेन अविश्वसनीय इनपुट पर कहाँ चलता है:
कौन प्रभावित है: datamodel-code-generator < 0.70.0 का कोई भी उपयोग जो (1) ऐसी स्कीमा से मॉडल जनरेट करता है जिसका customBasePath मान हमलावर-प्रभावित है, और (2) जनरेटेड मॉड्यूल को इम्पोर्ट या निष्पादित करता है। डिफ़ॉल्ट कोडजेन-फिर-इम्पोर्ट वर्कफ़्लो स्वाभाविक रूप से (2) को संतुष्ट करता है।
कौन प्रभावित नहीं है:
0.70.0 या उसके बाद के संस्करण पर, जहाँ customBasePath मान्य किया जाता है।| मीट्रिक | मान | स्रोत |
|---|---|---|
| कुल डाउनलोड | 194 मिलियन | pepy.tech/projects/datamodel-code-generator |
| पिछले 30 दिनों के डाउनलोड | 16.3 मिलियन | pepy.tech |
| विशिष्ट तैनाती | डेवलपर मशीनें, CI/CD पाइपलाइन, और SDK-जनरेशन प्लेटफ़ॉर्म जो OpenAPI / JSON Schema से कोडजेन करते हैं | टूल के कार्य में निहित |
customBasePath स्कीमा फ़ील्ड का मान बिना किसी आइडेंटिफ़ायर बाधा के जनरेटेड कोड में पहुँचाया जाता है। कोडबेस में तीन बिंदु महत्वपूर्ण हैं (पथ src/datamodel_code_generator/ के सापेक्ष):
parser/jsonschema.py फ़ील्ड custom_base_path को alias="customBasePath" के साथ परिभाषित करता है (~लाइन 644), जिसे कई कॉल साइटों पर _resolve_base_class(...) के माध्यम से उपभोग किया जाता है।parser/base.py, _resolve_base_class (~लाइन 1665), केवल स्थानीय normalize() (डेडुप/स्ट्रिप) के बाद मान लौटाता है। कोई आइडेंटिफ़ायर मान्यकरण लागू नहीं किया जाता।imports.py, Import.from_full_path() (~लाइन 35), मान को यथावत from ... import ... पंक्ति के रूप में उत्सर्जित करता है। मान का उपयोग model/base.py set_base_class (~लाइन 1324) में क्लास बेस के रूप में भी किया जाता है और मॉडल टेम्पलेट (class {{ class_name }}({{ base_class }}):) द्वारा कच्चा प्रस्तुत किया जाता है।चूँकि मान बिना किसी बाधा के Python सोर्स में लिखा जाता है, एम्बेडेड न्यूलाइन और डॉट-रहित एक्सप्रेशन आउटपुट में अपनी अलग-अलग पार्स-योग्य पंक्तियों के रूप में जीवित रहते हैं, और बीच की पंक्ति इम्पोर्ट पर निष्पादित होती है।
पेलोड आवश्यक रूप से डॉट-रहित है। Import.from_full_path मान को . पर विभाजित करता है, इसलिए एक सामान्य os.system(...) कॉल टूट जाएगा। getattr(__import__('os'),'system')(...) का उपयोग किसी भी . से बचते हुए समान कॉल को हल करता है, और आस-पास की न्यूलाइन उत्सर्जित from ... import ... पंक्तियों को वाक्य-रचना की दृष्टि से मान्य रखती हैं ताकि इंजेक्टेड बीच की पंक्ति साफ़-सुथरी चले।
यह ऐसा प्रोजेक्ट नहीं है जिसने इंजेक्शन की उपेक्षा की। अनुरक्षक ने कई परामर्शों (GHSA-5578, m34r, 8m8r, wjv6) में इसी श्रेणी को बार-बार सुरक्षित किया, हर बार कोड जनरेशन तक पहुँचने से पहले स्कीमा-नियंत्रित इम्पोर्ट या टाइप स्ट्रिंग को _validate_dotted_python_identifier_path के माध्यम से भेजा। सहोदर फ़ील्ड customTypePath (parser/jsonschema.py ~लाइन 4956, 5202 पर मान्य) और x-python-import (~लाइन 2096) दोनों उस वैलिडेटर से गुजरते हैं।
customBasePath एकमात्र ऐसा सहोदर है जिसमें ऐसा कोई कॉल नहीं है। यह उसी Import.from_full_path सिंक तक एक अलग पथ (_resolve_base_class) से पहुँचता है जो कभी भी उस मान्यकरण से नहीं जोड़ा गया जो अन्य फ़ील्ड को मिला। दोष इसलिए बचा रहा क्योंकि आस-पास की सुरक्षा पूर्ण दिखती थी: अनवैलिडेटेड इम्पोर्ट स्ट्रिंग की तलाश करने वाला समीक्षक पहले उन फ़ील्ड पर वैलिडेटर देखता है, और यह एक ऐसे हेल्पर से होकर गुजरता है जो इम्पोर्ट-हैंडलिंग के बजाय बेस-क्लास रिज़ॉल्यूशन जैसा दिखता है। यह एक व्यवस्थित सुधार में अंतराल है, अनुपस्थित सुधार नहीं, इसीलिए यह नवीनतम रिलीज़ में बना रहा।
एक हमलावर को चाहिए:
< 0.70.0 का उपयोग करने वाला लक्ष्य।customBasePath मान पर नियंत्रण, व्यवहार में इनपुट स्कीमा की आपूर्ति या उसे प्रभावित करके (एक तृतीय-पक्ष OpenAPI/JSON Schema दस्तावेज़, या किसी सेवा को प्रस्तुत स्कीमा)।हमलावर के लिए कोई प्रमाणीकरण या उन्नत विशेषाधिकार आवश्यक नहीं हैं (PR:N)। आधार स्कोर दर्शाता है कि पीड़ित सामान्य जनरेट-और-इम्पोर्ट क्रिया करता है (v3.1 में UI:R / v4.0 में UI:A); नेटवर्क-सेवा तैनाती उसे भी हटा देती है, और यहीं से पर्यावरणीय 9.8 आता है।
निम्नलिखित वास्तविक, अपरिवर्तित पैकेज के विरुद्ध चलाया गया। पुनरुत्पादन:
pip install "datamodel-code-generator==0.68.1"
datamodel-codegen --input attack.json --input-file-type jsonschema --output generated_models.py
python -c "import generated_models"
हमलावर का इनपुट (attack.json):
{
"type": "object",
"title": "User",
"customBasePath": "builtins import object\ngetattr(__import__('os'),'system')('whoami > RCE_PROOF.txt')\nfrom builtins.object",
"properties": { "name": { "type": "string" } }
}
कमजोर संस्करण (0.68.1) पर जनरेटेड generated_models.py: