Alerta de segurança do dompdf: vulnerabilidade de RCE encontrada em popular biblioteca PHP para PDF
DeveloperSteve Coochin
18 de março de 2022
0 minutos de leituraRecentemente, pesquisadores da Positive Security publicaram descobertas que identificam uma grave vulnerabilidade de execução remota de código (RCE) no dompdf, uma popular biblioteca de geração de PDFs. No relatório, eles descreveram uma forma de carregar código em um aplicativo e executá-lo remotamente durante a geração de um PDF.
O dompdf é bastante usado no ecossistema PHP e está presente em mais de 59 mil plataformas e projetos de código aberto. Só a página do dompdf no PHP Composer registra quase 50 milhões de instalações desde sua inclusão inicial no gerenciador de pacotes PHP, em 2014.
No momento da publicação deste artigo, ainda não há uma correção para essa vulnerabilidade. Uma possível solução é impedir o carregamento de estilos de fontes personalizados durante a geração de PDFs ou até restringir o acesso de gravação à pasta de cache de fontes. Outra boa opção é restringir o acesso ao diretório de instalação do Composer, dependendo das bibliotecas usadas e das funcionalidades necessárias no aplicativo.
Nas versões do dompdf => 0.8.6, a configuração $isRemoteEnabled pode ser desativada para impedir o carregamento de fontes personalizadas por meio de regras CSS font-face. No entanto, vale lembrar que isso pode causar problemas de compatibilidade. Além disso, nas versões <0.8.5, essa configuração não é usada e, portanto, não é possível corrigir essa vulnerabilidade com a configuração $isRemoteEnabled.
Neste artigo, vamos ver como a vulnerabilidade funciona. Para entender a fundo o código e as vulnerabilidades, em detalhes, acho útil colocar a mão na massa. Por isso, vamos explorar essa vulnerabilidade com uma demonstração prática usando o aplicativo php-goof, disponível em um repositório do Snyk no GitHub.
Bibliotecas para PDF
Gerar PDFs em aplicativos é uma das tarefas de que menos gosto como desenvolvedor. É um processo bastante longo e repetitivo: alterar o código, gerar o PDF, alterar o código, gerar o PDF e assim por diante, até acertar a formatação e o layout.
Mas poder converter HTML em PDF é extremamente útil, especialmente quando pensamos em quantas vezes os aplicativos precisam gerar PDFs. Isso acontece quase todos os dias, em sites de comércio eletrônico ou em sites que lidam com dados transacionais dos usuários e precisam gerar recibos para que eles possam salvar ou imprimir.
Por isso, para a maioria de nós, usar uma biblioteca para realizar esse tipo de tarefa no desenvolvimento de aplicativos ajuda a acelerar o processo. Bibliotecas como o dompdf permitem que nós, desenvolvedores, implementemos funcionalidades rotineiras e sigamos para tarefas mais complexas.
Colocando a mão na massa com a vulnerabilidade do dompdf
Ao analisar as descobertas de segurança originais, você entende melhor o que acontece dentro da biblioteca e como ela pôde ser explorada.
A biblioteca dompdf basicamente recebe HTML no formato usual e o transforma em um PDF formatado.
Ela oferece funcionalidades simples e fáceis de usar, eliminando uma tarefa bastante rotineira relacionada a uma funcionalidade muito comum. O melhor é que o PDF é formatado usando tags HTML padrão.
O HTML também pode incluir estilos. Eles podem ser inseridos diretamente na tag <html> ou por meio de uma folha de estilos. Com uma folha de estilos, você pode carregar uma font-family e incluir um link para um arquivo de fonte.
É aqui que as coisas começam a ficar interessantes.
A biblioteca dompdf não só carrega uma folha de estilos externa via HTML, como também salva o arquivo de fonte em um cache local, adiciona-o a um diretório de fontes no servidor e referencia a font-family e o local dentro da estrutura do dompdf.
A próxima etapa da exploração consiste em inserir código PHP em um arquivo de fonte que passe pela validação do dompdf e seja armazenado no servidor, mas que ainda permita a execução desse código PHP a partir do arquivo de fonte. Pode parecer complicado, mas os pesquisadores descobriram que a validação da biblioteca verifica apenas o tipo do arquivo, não seu conteúdo.
No aplicativo de demonstração php-goof, você pode ver como isso funciona analisando o arquivo de fonte personalizada chamado gotcha-normal.otf. Em sua maior parte, ele é mesmo um arquivo de fonte comum, com conjuntos de caracteres totalmente normais. Mas, na parte de metadados do arquivo, há código PHP para ser executado no servidor do aplicativo-alvo — <php? phpinfo(); ?> — dentro do campo de metadados de direitos autorais… Sim, é só isso!

Em seguida, abra o arquivo de fonte em um editor de código e copie o conteúdo para um arquivo .php, ou simplesmente renomeie o arquivo. Isso é importante porque o dompdf valida os cabeçalhos da fonte no arquivo e o salva no cache como um arquivo .php, permitindo que ele seja executado como PHP.
Em seguida, referencie esse novo arquivo de fonte falso no estilo CSS como uma font-family. No php-goof, fazemos isso diretamente a partir do repositório do php-goof.
Observação: É importante usar aqui o mesmo nome do arquivo de fonte para a font-family; caso contrário, não vai funcionar no dompdf.
Agora só falta inserir a folha de estilos no HTML usado para gerar o PDF. Isso fará com que o dompdf armazene a fonte no servidor, onde ela poderá ser executada remotamente. Essa etapa pode ser um pouco complicada, pois o nome do arquivo é transformado em um hash e o diretório de fontes pode estar em outro local.
No php-goof, essa parte fica um pouco mais fácil porque a estrutura do dompdf ajuda a identificar o local e o nome do arquivo de fonte. Ela usa $dompdf->getFontMetrics()->getFont(“gotcha”, “normal”) para verificar quando a fonte é detectada no cache de fontes do dompdf.
Quando o arquivo da fonte gotcha estiver disponível na estrutura, o sistema retornará o caminho como um link dentro do PDF gerado. Veja algumas capturas de tela da vulnerabilidade no aplicativo goof:



Mantenha-se seguro
Agradecemos à equipe da Positive Security não só por compartilhar suas descobertas com transparência, mas também pelas medidas que tomou para tentar comunicá-las aos responsáveis pela manutenção do dompdf.
Lembre-se sempre de analisar a base de código do seu aplicativo para identificar situações como essa, que podem surgir sem que você perceba. O Snyk Code ajuda a identificar vulnerabilidades em estruturas e funções, permitindo que você faça as verificações necessárias para proteger os usuários finais e seus dados.
Proteja suas dependências de código aberto
As ferramentas da Snyk, desenvolvidas para quem programa, criam PRs de correção com um clique para dependências de código aberto vulneráveis e suas dependências transitivas.
