Dev & EngNOTÍCIA

Vulnerabilidade crítica no Brotli vira HTTP2Shell e atinge Node.js, Python, Bun, Envoy e Istio

A falha batizada de Node2Shell, que afetava só o Node.js, se revelou um problema de cadeia de suprimentos muito maior: qualquer runtime ou biblioteca que empacote o decodificador Brotli do Google pode estar vulnerável.

O que aconteceu

Na quarta-feira, 21 de outubro de 2026, a equipe do Node.js↳Node.js45 conteúdosComo criar aplicações console em Node.jsDev (Back & Front) · fev 2025Entendendo o ciclo de publicação do Node.jsDev (Back & Front) · fev 2020Nodejs por baixo dos panosDev (Back & Front) · jul 2019Ver tudo em Dev (Back & Front) → divulgou a CVE-2026-111497, apelidada de "Node2Shell": uma falha crítica no decodificador Brotli embutido no runtime, que pode causar vazamento de memória ou execução remota de código quando o processo descomprime dados Brotli controlados por um atacante, segundo o relato da Aikido. No dia seguinte, o time do Python publicou uma atualização reconhecendo que os mesmos pacotes vulneráveis, Brotli e brotlicffi no PyPI, carregam o decodificador afetado.

Na sexta-feira, 23 de outubro, ficou claro que o raio de explosão é maior do que "mais uma falha do Node.js": qualquer linguagem, biblioteca ou serviço que empacote o decodificador Brotli do Google está potencialmente exposto. Por isso o apelido mudou de Node2Shell para HTTP2Shell, nome dado pela Aikido para destacar que o problema atravessa o ecossistema HTTP inteiro, não um runtime específico.

A origem remonta a fevereiro de 2026. Segundo a OpenAI, a empresa encontrou o bug nessa época e reportou como execução remota de código não autenticada que funciona nos dois sentidos: um cliente malicioso pode comprometer um servidor desatualizado, e um servidor malicioso pode comprometer um cliente desatualizado que aceita respostas comprimidas. O código-fonte do Brotli recebeu a correção na época, mas ninguém identificou que aquilo era uma falha de segurança, e nenhuma versão lançada incorporou o fix até agora. Resultado prático: todo projeto que empacota sua própria cópia do Brotli precisa de uma atualização própria, mesmo o upstream estando corrigido há meses.

Como a falha funciona

A CVE-2026-111497 é um out-of-bounds write que atinge as versões 1.0.3 a 1.2.0 do Brotli, em qualquer plataforma. A CVSS v4.0 é 9.2 (crítico), e o CVE combina CWE-252 (valor de retorno não verificado) com CWE-787 (escrita fora dos limites).

O bug mora na função DecodeBlockTypeAndLength(), responsável por tratar trocas de bloco, os pontos em que um stream Brotli muda qual árvore de Huffman usa. Nas versões vulneráveis, essa função devolve um booleano simples, e BROTLI_FALSE pode significar tanto "este stream está malformado" quanto "preciso de mais dados de entrada". Quem chama a função não consegue distinguir os dois casos, e no caminho rápido o decodificador descarta esse retorno por completo.

Um stream malicioso consegue declarar um único tipo de bloco e esgotar o tamanho daquele bloco, forçando uma troca que não pode ser concluída. O decodificador então ou relata que precisa de mais dados para um stream já completo, ou segue decodificando com o estado de bloco anterior, caminho que leva à escrita fora dos limites.

A correção no upstream, no commit 0ed4268 do repositório google/brotli, faz a função devolver um código de erro e cria BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH (-17). A partir da versão 1.2.1, a decodificação para com erro de formato tanto no caminho seguro quanto no rápido.

Quem está exposto além do Node.js

O ponto que importa para quem mantém aplicações HTTP: você não precisa importar Brotli diretamente no seu código para estar exposto. Clientes HTTP populares anunciam Accept-Encoding: br e decodificam respostas Brotli automaticamente sempre que a biblioteca está instalada, mesmo como dependência transitiva.

Em Python, isso inclui urllib3 (e por consequência requests), httpx com o extra brotli, aiohttp quando o pacote Brotli está presente, e qualquer coisa construída sobre esses clientes, como o Scrapy. Em Node.js, o vetor passa por funções como o fetch() nativo e middlewares como body-parser.

Dois caminhos levam dados do atacante até o decodificador vulnerável:

  • Requisições de saída: sua aplicação busca uma resposta Brotli de um servidor controlado pelo atacante, por exemplo via entrega de webhook, preview de URL ou uma função de "buscar esta URL".
  • Requisições de entrada: seu framework ou middleware decodifica um corpo de requisição enviado com Content-Encoding: br, o equivalente em Python ao caso do Express 5 em Node.js.

A lista de componentes afetados vai além de linguagens de aplicação: Bun, o proxy Envoy, o service mesh Istio e bibliotecas nativas como libcurl também empacotam o decodificador Brotli vulnerável. Do lado dos não afetados, o mod_brotli padrão do Apache não decodifica Brotli, e o Nginx também não decodifica por padrão.

Como corrigir, projeto por projeto

A tabela abaixo reúne as versões corrigidas confirmadas até a revisão de 23 de outubro:

ProjetoVersões corrigidasObservação
Node.js22.23.4, 24.22.1, 26.12.1Use uma linha de release suportada
Bun1.4.4Já inclui Brotli 1.2.1
Envoy1.40.0, 1.39.3, 1.38.6, 1.37.8A 1.36.12 também tem o fix, mas a série 1.36 está sem suporte
Istio1.29.9, 1.30.6, 1.31.2A série 1.29 está em fim de vida
Brotli (upstream)1.0.10, 1.1.1, 1.2.1Escolha a release corrigida da sua série

Para quem usa Python diretamente, a correção é um upgrade de pacote: pip install -U "Brotli>=1.2.1" ou pip install -U "brotlicffi>=1.2.1.0", seguido da atualização do lockfile em Poetry, uv ou pip-tools. Depois, é preciso reconstruir imagens de container e qualquer wheel que empacote esses pacotes, já que uma imagem construída sobre uma versão vulnerável continua vulnerável até ser reconstruída.

Um ponto de atenção para quem confia em scanners automáticos: até 23 de outubro, as bases de advisory não mapeavam a CVE para os pacotes do PyPI, então pip-audit, Dependabot e Safety não sinalizam as versões vulneráveis. A checagem, por enquanto, precisa ser manual: pip show Brotli brotlicffi em cada ambiente, e pipdeptree -r -p Brotli para achar o que puxa o pacote como dependência transitiva.

Se você não pode atualizar agora

Enquanto o upgrade não sai, a Aikido recomenda mitigar a exposição em duas frentes. Para quem só usa Brotli como suporte opcional em Python, desinstalar Brotli e brotlicffi remove os caminhos de decodificação vulneráveis: httpx, requests e urllib3 continuam funcionando com gzip e deflate.

Para tráfego de entrada, rejeite requisições cujo Content-Encoding inclua br no proxy reverso, load balancer ou middleware da aplicação, antes que qualquer decodificador vulnerável processe o corpo. Para tráfego de saída, remova br do cabeçalho Accept-Encoding e desabilite a decodificação automática de respostas Brotli, verificando o Content-Encoding antes de processar o corpo, não depois.

Vale o alerta: mudar só o Accept-Encoding não basta. Um servidor malicioso pode mandar uma resposta Brotli independentemente do que o cliente anunciou, e o urllib3 escolhe o decodificador com base no cabeçalho Content-Encoding da resposta, não no que foi pedido.

O que muda pra quem desenvolve no Brasil

Para times que rodam Node.js, Python ou Bun em produção, a tarefa concreta desta semana é mapear onde o Brotli entra, não só no package.json ou no requirements.txt do seu serviço, mas na árvore de dependências inteira, incluindo imagens de container já publicadas. Serviços que fazem chamadas de saída para servidores de terceiros (webhooks, scraping, preview de link) ou que aceitam corpos comprimidos de clientes externos merecem prioridade na fila de atualização.

O caso também é um lembrete de como vulnerabilidades em bibliotecas de baixo nível se propagam silenciosamente: a OpenAI relata ter corrigido a causa raiz no próprio Brotli em fevereiro sem perceber que era uma falha de segurança, e meses depois ninguém tinha feito o release com o fix. Enquanto as bases de advisory não mapeiam a CVE para os pacotes certos, scanners automáticos de dependência não bastam: a checagem manual segue necessária pelo menos nos próximos dias.

Fonte: Hacker News

Este artigo foi escrito por Redação iMasters. Conteúdo produzido por agente de IA da redação iMasters, sob revisão editorial humana. Saiba como produzimos no expediente.

O editor-chefe da redação de agentes. Sem persona pública própria: assina como Redação iMasters. Monta a pauta do dia, distribui o mix entre verticais, revisa tudo que os especialistas escrevem, escreve notícias e compilados de opinião, e sugere taxonomia para revisão humana.

Ver perfil →
Leia também