← back
CVE-2025-23209highunder attackCWE-94

Potential RCE with a compromised security key in craft/cms

56Vexday Risk Score

Prioritize patching. It under exploitation confirmed by CISA.

ssvc Actcvss 8.1epss 22%
from disclosure to weapon
Published on NVDJan 18
CISA KEV+33d
exploitation probability
22%top 2% of all CVEs
observed exploitation
yesCISA + VulnCheck
Action required by CISAfederal deadline: 2025-03-13

Apply mitigations per vendor instructions or discontinue use of the product if mitigations are unavailable.

Summary

Falha de code injection (CWE-94) no fluxo de restauração de backup de banco de dados do Craft CMS, que permite RCE completo no servidor — mas apenas se a security key da aplicação já estiver comprometida. O CVSS de 8.1 é alto, porém o pré-requisito (posse da security key) restringe bastante quem está realmente exposto: não é uma falha explorável remotamente por um atacante anônimo sem esse segredo.

Technical detail

O problema está em UpdaterController::actionRestoreDb(). O método chamava Craft::$app->getDb()->restore($this->data['dbBackupPath']) passando diretamente um caminho de arquivo vindo de dados controlados pelo cliente, sem validar se esse caminho existia ou se estava contido dentro do diretório oficial de backups (storage/backups). O comando de restore do Yii2/Craft monta e executa uma chamada de shell (mysql/pg_restore, dependendo do driver de banco) usando esse caminho como argumento — se o valor puder ser manipulado, o atacante injeta comando arbitrário ou faz o processo tratar um arquivo arbitrário do disco como se fosse um dump de banco, alcançando execução de código no servidor. É classificado pela CISA como CWE-94, code injection causado por validação inadequada do caminho de backup do banco.

O campo $this->data que alimenta o dbBackupPath não é um parâmetro de request comum e aberto: no fluxo do Updater, esses dados normalmente são protegidos/assinados usando a security key da aplicação (o segredo criptográfico configurado em config/general.php ou via variável de ambiente, usado por Craft::$app->getSecurity() para validar/decriptar payloads). Isso explica por que a falha só é explorável quando a security key já foi comprometida: sem ela, o atacante não consegue forjar um payload de dados válido que o controlador aceite processar com um dbBackupPath arbitrário.

A correção (commit e59e22b) adiciona duas verificações antes de chamar restore(): file_exists($backupPath) e FileHelper::isWithin($backupPath, Craft::$app->getPath()->getDbBackupPath()), lançando BadRequestHttpException se o caminho não existir ou estiver fora do diretório de backups esperado. Ou seja, o patch não elimina a necessidade de proteger a security key — ele fecha a porta de escape de diretório/injeção que a posse da key abria.

How it’s exploited

Pré-requisito indispensável e raramente destacado no título da CVE: o atacante precisa já possuir a security key da instalação Craft. Isso normalmente vem de exposição de .env, config/general.php, repositórios de código vazados, backups de arquivos acessíveis publicamente, ou outra falha anterior que leia arquivos de configuração. Sem a key, o endpoint do Updater não aceita um payload de dados forjado e a cadeia de exploração não se completa — por isso AV:N mas AC:H no vetor CVSS.

Com a key em mãos, o atacante forja o payload de dados que o UpdaterController espera (o campo que carrega dbBackupPath), definindo esse caminho para um arquivo sob seu controle ou para explorar a ausência de contenção de diretório, disparando a rotina de restauração de banco. Como o valor do caminho chega sem sanitização até o comando de restore executado via shell, isso resulta em execução de código arbitrário no servidor, com o mesmo nível de privilégio do processo PHP/Craft (potencialmente todo o container ou VM da aplicação).

A CVE está no catálogo KEV da CISA (adicionada em 2025-02-20, prazo de correção 2025-03-13), confirmando exploração ativa observada, embora a CISA não indique se há uso em campanhas de ransomware. A necessidade de posse prévia da security key sugere que a exploração em massa provavelmente ocorreu em conjunto com outras falhas ou exposições que vazaram esse segredo — não é um ataque de um único passo contra qualquer instalação Craft na internet.

Versions

Affected
Craft 5: >= 5.0.0-RC1 e = 4.0.0-RC1 e < 4.13.8 (conforme publicado no GitHub Security Advisory GHSA-x684-96hh-833x).
Fixed in
Craft 5.5.8 e Craft 4.13.8 (backport para o ramo 4).

How to protect

Atualizar para Craft 5.5.8 (ramo 5) ou 4.13.8 (ramo 4), que adicionam validação de existência e contenção do caminho de backup dentro do diretório oficial antes de executar o restore. Essa é a correção real da causa raiz (a falta de validação do path) e deve ser aplicada independentemente de você acreditar que sua security key está segura.

Se a atualização não for possível agora, o fornecedor recomenda rotacionar a security key imediatamente e garantir que ela não fique exposta (fora de repositórios versionados, fora do webroot, lida por variável de ambiente). Isso remove o pré-requisito de exploração — mas é mitigação parcial: se a causa que expôs a key originalmente persistir (por exemplo, .env acessível via HTTP, painel de configuração exposto, backup de código-fonte público), uma nova key pode ser comprometida da mesma forma e o problema reaparece.

Não funciona como mitigação apenas restringir acesso ao painel administrativo do Craft sem tratar a exposição da security key nem aplicar o patch — a falha de validação do caminho de backup continua presente até a atualização, e a chave, uma vez vazada, compromete toda a proteção que dados assinados oferecem no restante da aplicação, não só neste endpoint.

How to detect

Nos logs de erro do Craft/PHP, procure por exceções BadRequestHttpException com mensagem 'Invalid backup path' — isso indica que o patch está ativo e bloqueou uma tentativa de path fora do diretório de backups ou inexistente; sua ausência em versão não corrigida não significa ausência de tentativa, apenas que o comando de restore não logava esse tipo de rejeição antes do patch. Verifique também requisições HTTP dirigidas às rotas de ações do controller de Updater (fluxo de atualização/restore do Craft) fora do horário normal de manutenção/deploy.

Não há assinatura de payload pública conhecida, já que a exploração depende de um segredo específico da instalação (a security key) — não existe um indicador de comprometimento genérico aplicável entre diferentes instalações Craft. O sinal mais confiável de risco não é tráfego, e sim auditoria: verificar se a security key da instalação já foi exposta em algum momento (histórico de repositório, backups públicos, logs de erro com stack trace, arquivos .env acessíveis).

Researched and written with AI from the vendor advisory and public analysis, with the sources above. Always confirm the fixed version in the official advisory before acting.
Craft is a flexible, user-friendly CMS for creating custom digital experiences on the web and beyond. This is an remote code execution (RCE) vulnerability that affects Craft 4 and 5 installs where your security key has already been compromised. Anyone running an unpatched version of Craft with a compromised security key is affected. This vulnerability has been patched in Craft 5.5.8 and 4.13.8. Users who cannot update to a patched version, should rotate their security keys and ensure their privacy to help migitgate the issue.
CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:C/C:H/I:H/A:H
Affected products
craftcms · cms