Uma falha no Brotli, muitos produtos afetados: CVE-2026-111497 chega ao Node.js, Bun, Python e Envoy
Uma falha de segurança de memória na biblioteca de referência para descompressão Brotli transformou-se num exercício de correção que atravessa vários ecossistemas. Identificada como CVE-2026-111497, permite que dados comprimidos em Brotli especialmente preparados escrevam para além do fim de um buffer. Como o mesmo descodificador está integrado em runtimes, proxies e bibliotecas Python, a correção tem de chegar produto a produto — e alguns ainda estão a recuperar o atraso.
O que aconteceu
A 21 de outubro de 2026 foram publicadas versões corrigidas do Node.js e uma biblioteca Brotli atualizada, e nos dias seguintes foram surgindo correções para o restante software afetado. A alteração que fecha a falha entrou, na verdade, no código-fonte do Brotli em fevereiro, mas na altura ninguém a reconheceu como uma correção de segurança e nenhuma versão do Brotli a incluiu até outubro — pelo que os projetos dependentes continuaram, durante meses, a distribuir o descodificador vulnerável.
Uma carga maliciosa pode corromper a memória e provocar uma falha, uma fuga de memória ou, no pior dos casos, a execução de código controlado pelo atacante. A execução remota de código foi demonstrada numa única compilação sem correção — Node.js 24.22.0 para Linux em ARM64 —, tanto através de uma resposta obtida com fetch como de um corpo de pedido carregado. Foram necessárias várias tentativas, o exploit não foi divulgado e não foi demonstrada execução de código nos restantes produtos afetados. Não foi reportada exploração ativa, nem existe uma prova de conceito pública fiável.
A gravidade depende de quem a avalia: o CVE tem uma pontuação crítica de 9,2 em CVSS 4.0, enquanto alguns fornecedores o classificam como alto ou importante (cerca de 8,1).
Quem é afetado
| Software | Vulnerável | Corrigido | Exposto quando |
|---|---|---|---|
| Node.js | versões anteriores à atualização de segurança de 21 de outubro | versões de segurança de 21 de outubro | fetch() lê uma resposta br, ou um body parser descomprime um upload Brotli |
| Bun | 1.4.3 e anteriores | 1.4.4 | fetch() lê uma resposta br, ou o código usa node:zlib |
| Envoy | até 1.39.2, 1.38.5, 1.37.7, 1.36.11 | 1.40.0, 1.39.3, 1.38.6, 1.37.8, 1.36.12 | o descompressor Brotli está configurado |
| Istio | 1.31.0–1.31.1, 1.30.0–1.30.5, 1.29.0–1.29.8 | 1.31.2, 1.30.6, 1.29.9 | a descompressão Brotli está ativada |
Python Brotli | 1.2.0 e anteriores | 1.2.1 | instalado, e um cliente HTTP descodifica br |
Python brotlicffi | 1.2.0.x e anteriores | 1.2.1.0 | instalado, e um cliente HTTP descodifica br |
| cdxgen | binários/imagens autónomos 13.4.0, 12.8.8 e anteriores | 13.5.0, 12.8.9 | analisa input não fidedigno |
Porque é importante
A pergunta decisiva é simples: o seu software descodifica dados Brotli controlados por terceiros?
- Node.js e Bun ficam expostos quando o
fetch()integrado recebe uma resposta enviada comContent-Encoding: br, ou quando um middleware de corpo de pedido — por exemplo, Express 5 com body-parser 2 — descomprime um upload Brotli. Um servidor HTTP Node.js simples não descodifica sozinho o corpo dos pedidos. - Envoy e Istio só são atingíveis quando a descompressão Brotli está ativada, por exemplo através de um filtro Envoy. Se estiver desativada, a falha não pode ser desencadeada.
- Python é o caso mais traiçoeiro. Basta ter
Brotlioubrotlicffiinstalado: clientes HTTP populares como requests, urllib3, httpx e aiohttp utilizam-nos automaticamente e descodificam sozinhos as respostas Brotli. Uma aplicação pode ficar exposta sem nunca importar Brotli no seu próprio código.
A falha funciona também nos dois sentidos. Um servidor sem correção que aceite input comprimido pode ser tomado por um cliente malicioso, e um cliente sem correção que aceite respostas comprimidas pode ser tomado por um servidor malicioso. Uma firewall de aplicações web pode filtrar o tráfego de entrada, mas não protege as respostas que o seu próprio código obtém de outros servidores — nesse caminho, só a atualização fecha a brecha.
Dois pontos cegos dificultam o acompanhamento. O registo do CVE aponta para o repositório original do Brotli e não para os pacotes PyPI, pelo que os scanners de dependências que se baseiam nos avisos do GitHub podem ainda não assinalar as bibliotecas Python; as entradas específicas (PYSEC-2026-4322 e PYSEC-2026-4323) só foram adicionadas a 23 de outubro. Além disso, os pacotes de sistema avançam a ritmos diferentes: o Debian 13 (trixie) publicou um pacote brotli corrigido (1.1.0-2+deb13u1) a 23 de outubro, enquanto o Amazon Linux 2023 ainda indicava os seus pacotes brotli e Node.js 24 como a aguardar correção a 22 de outubro.
O que fazer
- Atualize para uma versão corrigida da tabela acima e, em seguida, reinicie os serviços e reconstrua as imagens de contentor — um processo em execução mantém o descodificador antigo em memória até ser reiniciado.
- Se ainda não puder atualizar, deixe de descodificar Brotli não fidedigno:
- rejeite pedidos recebidos com
Content-Encoding: brantes de qualquer proxy ou parser descodificar o corpo; - desative a descodificação automática de Brotli nos clientes HTTP e rejeite respostas Brotli antes de serem descodificadas;
- em Python, desinstale
Brotliebrotlicffipara que os clientes recorram a gzip e deflate.
- rejeite pedidos recebidos com
- Não confie apenas no
Accept-Encoding. Retirarbrdesse cabeçalho não é, por si só, uma defesa — um servidor hostil pode enviar Brotli independentemente do que o cliente pede. Para o Node.js não existe qualquer mitigação publicada: atualizar o runtime é a correção. - Verifique manualmente, não apenas com o seu scanner. Execute
pip show brotli brotlicffiem todos os ambientes e imagens Python e acompanhe os pacotes brotli e Node.js da sua distribuição até estarem corrigidos.
Falhas como esta escondem-se em dependências opcionais e transitivas que ninguém escolheu de propósito. A revisão de código assistida por IA da nossa equipa inventaria aquilo que as suas aplicações carregam realmente — incluindo bibliotecas que os clientes HTTP utilizam em silêncio — e cruza-o com os avisos de segurança atuais, para que um descodificador vulnerável não fique invisível só porque o seu código nunca o importa diretamente.
