Skip to content
KitploitKITPLOIT
FerramentasExploitsBlog
Log in
Enviar
FerramentasExploitsBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

FeedsContatoPrivacidade© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
Ferramentas/GitHubGitHub/filipegaudard/
cve-2026-35045-poc
Análise de VulnerabilidadesExploraçãoExploração de Aplicações WebTestes de Segurança de APIsTestes de PenetraçãoAprendizado e Educação
GitHubfilipegaudard/cve-2026-35045-poc

CVE-2026-35045-PoC

Prova de conceito de exploit para CVE-2026-35045, uma vulnerabilidade de autorização quebrada em nível de objeto no Tandoor Recipes, demonstrando modificação não autorizada de receitas por meio do endpoint da API batch_update.

Ver Repositório
1119há 6 mesesAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

CVE-2026-35045 — Quebra de Autorização em Nível de Objeto no Tandoor Recipes

CVE-2026-35045 GHSA CVSS 8.1 CWE-639

Affected Version Responsible Disclosure


Resumo

O endpoint PUT /api/recipe/batch_update/ no Tandoor Recipes v2.6.1 permite que qualquer usuário autenticado dentro de um Espaço modifique qualquer receita naquele Espaço — incluindo receitas privadas de outros usuários. Isso contorna completamente as verificações de autorização em nível de objeto aplicadas em todos os endpoints padrão de receita individual.

A causa raiz é uma lacuna comportamental do Django REST Framework: ações de lista com detail=False nunca invocam has_object_permission(), apenas has_permission(). O queryset filtra somente por space=request.space, sem verificação de created_by, private ou da lista shared. Um atacante pode forçar a exposição de receitas privadas, conceder a si mesmo acesso persistente, revogar permissões de outros usuários e adulterar metadados — tudo em uma única chamada de API que retorna HTTP 200 OK com corpo vazio.

Detalhes da Vulnerabilidade

CampoValor
ID CVECVE-2026-35045
GHSAGHSA-v8x3-w674-55p5
CWECWE-639 — Bypass de Autorização Através de Chave Controlada pelo Usuário
CVSS v3.18.1 ALTA — AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
Versão AfetadaTandoor Recipes ≤ 2.6.1
FornecedorTandoorRecipes/recipes

Mapeamento MITRE ATT&CK

ID da TécnicaNomeRelevância
T1078Contas VálidasO atacante usa credenciais legítimas de baixo privilégio para contornar a autorização
T1565.001Manipulação de Dados ArmazenadosModificação de receitas privadas e ACLs de outros usuários

Análise da Causa Raiz

1. detail=False Contorna Verificações de Permissão em Nível de Objeto

Arquivo: 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   # ← Sem verificação de created_by ou private
        )

No Django REST Framework, ações registradas com detail=False são ações de lista. Elas nunca chamam get_object(), o que significa que check_object_permissions() e CustomRecipePermission.has_object_permission() nunca são invocadas. Apenas has_permission() é executada — que verifica a associação ao Espaço, não a propriedade da receita.

2. Endpoints Padrão São Protegidos Corretamente

PUT /api/recipe/{id}/ segue o fluxo completo de permissões do DRF:

get_object()
  → check_object_permissions()
    → CustomRecipePermission.has_object_permission()
      → nega acesso se a receita for privada e não pertencer/for compartilhada com o solicitante

O endpoint batch_update pula silenciosamente toda essa cadeia.

3. Campos Graváveis via Lote

RecipeBatchUpdateSerializer expõe os seguintes campos — graváveis em qualquer receita do Espaço:

CampoEfeito
privateAlterna a visibilidade da receita
shared_add / shared_remove / shared_setManipula a lista de controle de acesso
keywords_add / keywords_remove / keywords_setAltera os metadados da receita
working_time / waiting_timeModifica os dados de tempo da receita

Fluxo do Ataque

┌──────────┐   ① PUT /api/recipe/batch_update/    ┌─────────────────┐
│ Atacante │ ─────────────────────────────────────→│  Servidor Tandoor│
│ (Usuário B)│   {"recipes":[2],"private":false,     │                 │
│          │    "shared_add":[2]}                  │  has_permission()│
└──────────┘                                       │  ✓ (Membro do Espaço)│
                                                   │                 │
                                                   │  has_object_    │
                                                   │  permission()   │
                                                   │  ✗ NUNCA CHAMADA│
                                                   └────────┬────────┘
                                                            │
                                              ② Recipe.objects.filter(
                                                 id__in=[2],
                                                 space=request.space
                                              )  ← Sem verificação de propriedade
                                                            │
                                                            ▼
                                                   ┌────────────────┐
                                                   │  Receita ID 2  │
                                                   │  (de A)        │
                                                   │  private=false ← corrigido
                                                   │  shared=[2]  ← autoconcedido
                                                   └────────┬───────┘
                                                            │
                                              ③ HTTP 200 OK — {}
                                                            │
                                                            ▼
                                                   ┌────────────────┐
                                                   │ Atacante (B)   │
                                                   │ agora tem      │
                                                   │ acesso total   │
                                                   │ à Receita ID 2 │
                                                   └────────────────┘

Prova de Conceito

Requisitos

  • Python 3.10+
  • Biblioteca requests
pip install requests

Uso

# Forçar exposição de uma receita privada e autoconceder acesso (padrão)
python3 poc.py --url http://127.0.0.1:8085 \
               --username userB --password passB \
               --recipe-id 2 \
               --attacker-user-id 2

# Apenas forçar exposição (definir 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

# Apenas autoconcessão (adicionar à lista shared, manter 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

Módulos / Ações

Baixar ferramenta