HTTP2Shell: falha no Brotli afeta Node.js, Python e .NET

Uma vulnerabilidade no decodificador Brotli está forçando atualizações emergenciais em três ecossistemas ao mesmo tempo: Node.js, bibliotecas HTTP do Python e .NET. A falha, catalogada como CVE-2026-111497 e apelidada de “HTTP2Shell” (também circulando como “Broccoli2Shell” e “Node2Shell”), foi identificada primeiro no Node.js e depois confirmada no decodificador Brotli em si, o que explica por que o problema se espalhou para outras linguagens que usam a mesma biblioteca de compressão. A Imperva já demonstrou execução remota de código funcional contra Express e contra o fetch() nativo do Node.js, segundo reportagem da BleepingComputer.

Resumo para quem decide

  • O que é: buffer overflow no decodificador Brotli, biblioteca de compressão do Google embutida no Node.js e usada por clientes HTTP em Python e pelo .NET.
  • Quem é afetado: Brotli 1.0.3 a 1.0.9, 1.1.0 e 1.2.0; Node.js 22.x, 24.x e 26.x; clientes HTTP Python com decodificador Brotli habilitado (urllib3, requests, httpx, aiohttp); aplicações .NET com versão vulnerável do runtime.
  • Severidade: o Node.js classifica como “high” (alta). A cobertura da imprensa usa “critical”. Essa divergência importa para quem prioriza patches por rótulo em vez de validar o impacto.
  • Exploração ativa: não havia relatos de exploração maliciosa até 26 de outubro. Existem PoCs públicas, e a Imperva reproduziu RCE em ambiente controlado.
  • Ação imediata: atualizar Node.js para 22.23.4, 24.22.1 ou 26.12.1 (ou Brotli 1.0.10/1.1.1/1.2.1, ou Python brotli 1.2.1 / brotlicffi 1.2.1.0, conforme o stack), aplicar a atualização emergencial do .NET publicada pela Microsoft, reiniciar os processos afetados e reconstruir e publicar de novo as imagens de contêiner.

O que é a vulnerabilidade HTTP2Shell

Como o buffer overflow acontece no decodificador Brotli

O problema está em como o decodificador Brotli trata uma transição de bloco (“block switch”) inválida dentro de um stream comprimido malformado. Em vez de reconhecer essa transição como um erro permanente de formato, o decoder a interpreta como uma necessidade temporária de mais dados de entrada. Com isso, ele continua anexando bytes a um buffer interno de apenas 8 bytes, escrevendo além do limite alocado e corrompendo memória adjacente.

A correção publicada pelo projeto Brotli corrige exatamente esse comportamento: agora, ao encontrar essa transição inválida, o decoder retorna um erro de formato e repassa essa falha ao código que o chamou, em vez de seguir processando dados fora de controle.

O impacto documentado pelo Node.js inclui queda do processo, exposição de memória interna da aplicação e execução remota de código. A exploração acontece de duas formas: uma aplicação que busca uma URL externa recebe uma resposta HTTP comprimida maliciosa, ou um servidor recebe diretamente uma requisição comprimida com o payload malicioso. No Node.js, o caminho de entrada passa pelo módulo node:zlib, usado por qualquer aplicação que descomprima dados Brotli fornecidos por terceiros.

A descoberta foi reportada por Khai Tran e Sylvie Mayer, da OpenAI Codex Security, segundo o advisório oficial do Node.js. A correção é creditada a Matteo Collina (mcollina) e Antoine du Hamel (aduh95).

Por que a severidade divide opiniões: “high” vs “critical”

Vale registrar essa diferença de linguagem explicitamente: o advisory oficial do Node.js trata CVE-2026-111497 como “high”, não “critical”. Quem decide prioridade de patch com base só na manchete corre o risco de superestimar ou subestimar o risco real sem olhar o texto técnico do fabricante. Na dúvida, a referência é o texto do fabricante: o advisory do Node.js descreve corrupção de memória que pode levar a queda do processo, vazamento de memória ou execução remota de código, e isso basta para tratar a correção como prioritária.

Quais sistemas e produtos estão em risco

Node.js, a biblioteca Brotli em C e o patch do .NET

A biblioteca Brotli em C, mantida pelo Google, está vulnerável nas versões 1.0.3 a 1.0.9, 1.1.0 e 1.2.0. O Node.js embute essa biblioteca internamente e está afetado nas linhas 22.x, 24.x e 26.x. A Microsoft também lançou um patch emergencial para .NET, já que sistemas com versão vulnerável do runtime ficam expostos a risco de escalonamento de privilégios.

Clientes HTTP em Python (urllib3, requests, httpx, aiohttp)

Clientes HTTP Python como urllib3[brotli], requests, httpx e aiohttp[speedups] ficam potencialmente afetados quando configurados com um decodificador Brotli vulnerável. O pacote Python brotli corrigido é a versão 1.2.1; o brotlicffi corrigido é a versão 1.2.1.0.

Express e body-parser: o caminho testado pela Imperva

A Imperva cobriu as faixas Express 5.0.0 a 5.3.0 e body-parser 2.0.0 a 2.3.0 testando versões pontuais delas (Express 5.0.0 e 5.3.0; body-parser 2.0.0, 2.0.1 e 2.3.0), sem testar cada versão intermediária, sobre a imagem oficial Node.js 24.22.0 Linux arm64. Esse recorte importa porque um servidor Node.js HTTP puro, sem middleware configurado, não decodifica automaticamente corpos de requisição Brotli recebidos. Esse caminho se abre quando há um parser de corpo configurado, como os do Express e do body-parser, ou quando o próprio código da aplicação descomprime com node:zlib dados Brotli vindos de fora. O Express 5 documenta suporte à decodificação Brotli em seus parsers de corpo de requisição, e o body-parser suporta isso desde a versão 2.0.0.

A Imperva deixa claro que cobriu apenas a build oficial Linux arm64 e configurações específicas de aplicação, sem testar todas as builds do Node.js nem todas as combinações de versão possíveis.

Prova de conceito: como a Imperva confirmou a execução remota de código

Ataque pelo lado cliente: respostas HTTP maliciosas consumidas via fetch()

A Imperva construiu uma PoC standalone contra contêineres frescos rodando a imagem oficial Node.js 24.22.0 Linux arm64, sem necessidade de debugger ou binário instrumentado. Um dos caminhos testados foi uma resposta HTTP comprimida consumida pelo fetch() nativo do Node.js. Na versão 24.22.0, o código suprido pelo atacante foi executado, com a criação de um marcador de prova. Na versão corrigida 24.22.1, a mesma entrada foi rejeitada e nenhum marcador foi criado.

Esse resultado é relevante porque muda o raciocínio padrão sobre exposição: não é só o lado servidor que processa entrada de atacante. Qualquer aplicação que faz chamadas de saída e consome respostas comprimidas de terceiros, via fetch() ou bibliotecas HTTP equivalentes, também está no caminho de ataque.

Ataque pelo lado servidor: corpo de requisição processado por Express/body-parser

O segundo caminho testado foi o corpo de requisição tratado pelos parsers raw() e json() do Express e do body-parser. O comportamento foi o mesmo: na versão 24.22.0, o código executou e criou o marcador; na versão corrigida, a entrada foi rejeitada e o servidor continuou no ar.

Um detalhe importante é que a execução da PoC “levou múltiplas tentativas” no ambiente da Imperva, ou seja, não funcionou em todas as execuções. Isso não reduz a gravidade, mas indica que a exploração não é trivialmente determinística em todas as condições. A Imperva também usou um sanitizador de memória separadamente para confirmar a causa raiz: a continuação do processamento após a condição inválida é o que gera a escrita fora dos limites.

Vale notar que a falha foi reportada pela OpenAI Codex Security. A própria Imperva liga o caso ao PHP2Shell, RCE crítico no interpretador PHP, em que pesquisadores usaram IA para achar e explorar falhas antigas de memória: a IA acelera tanto a descoberta quanto a construção do exploit, e encurta o prazo entre divulgação e ataque. O tema já apareceu aqui no caso do zero-day no Apache descoberto com ajuda de IA.

Como corrigir e mitigar a HTTP2Shell

Versões corrigidas e por que atualizar a lib do sistema não basta

As versões corrigidas disponíveis são:

  • Brotli (C): 1.0.10, 1.1.1, 1.2.1.
  • Node.js: 22.23.4, 24.22.1, 26.12.1.
  • Python brotli: 1.2.1. Python brotlicffi: 1.2.1.0.

As correções no código-fonte do Brotli entraram no projeto em fevereiro. Node.js e Google lançaram as versões estáveis corrigidas em 21 de outubro de 2026. Os pacotes PyPI corrigidos ficaram disponíveis em 23 de outubro.

Um ponto crítico de gestão de dependências: atualizar a biblioteca Brotli do sistema operacional não resolve o risco em deployments Node.js nem em outras aplicações que carregam uma cópia própria da biblioteca, o que é exatamente o caso do runtime Node.js. Se sua aplicação roda em contêiner, atualizar a imagem base do sistema operacional sem reconstruir e publicar de novo a imagem da aplicação deixa a falha intacta. A Imperva reforça: um inventário de pacotes pode não enxergar um Node.js antigo embutido no contêiner, por isso a versão precisa ser conferida dentro de cada imagem e servidor. Depois de atualizar, reinicie os processos afetados.

Mitigações temporárias quando o patch imediato não é possível

Bloquear requisições Brotli recebidas no nível de proxy ou firewall ainda deixa exposta a rota de resposta HTTP maliciosa, nos casos em que a própria aplicação consome respostas comprimidas de terceiros via fetch() ou bibliotecas HTTP. Por isso a mitigação completa exige atenção aos dois sentidos do tráfego, não só à entrada.

Se a atualização imediata não for possível, as recomendações são:

  • Remover o suporte a Brotli de aplicações Python que não dependem estritamente dele.
  • Bloquear requisições comprimidas em Brotli recebidas no nível de proxy ou firewall, como medida parcial.
  • Considerar virtual patching via WAF como medida de ganho de tempo. A Imperva afirma ter adicionado regras de WAF dedicadas para CVE-2026-111497, validadas para detectar e bloquear as tentativas de exploração que conseguiu reproduzir, recomendando essa camada como ponte até a atualização completa do runtime.

Mesmo sem exploração ativa confirmada até agora, PoCs públicas já circulam, o que reduz a margem de segurança para adiar o patch. E, ao contrário de casos como o AhsayCBS, explorado sem correção disponível, aqui a correção já existe: a prioridade é aplicar e publicar de novo, não esperar.

Vale lembrar também que o mesmo pacote de segurança do Node.js lançado em 21 de outubro de 2026 (versões 22.23.4, 24.22.1, 26.12.1) corrigiu outras falhas não relacionadas ao Brotli, incluindo falhas na verificação de hostname do TLS, truncamento de nomes em dns.resolve*(), reuso indevido de socket keep-alive, entropia repetida em crypto.randomUUID() e brechas no Permission Model. Quem atualiza para essas versões por causa do HTTP2Shell já resolve esse conjunto adicional de correções no mesmo processo.

Perguntas frequentes

Já existe exploração ativa da HTTP2Shell?
Até 26 de outubro não havia relatos de exploração maliciosa confirmada. Existem PoCs publicadas publicamente, e a Imperva reproduziu RCE em ambiente de teste controlado, mas isso é diferente de exploração confirmada em produção. Essa distinção não deve ser confundida com “sem risco”: casos como o BIG-IP APM da F5, com zero-day já explorado ativamente permitindo RCE sem autenticação, mostram a diferença de urgência entre “PoC pública sem exploração confirmada” e “exploração ativa em andamento”. No caso do HTTP2Shell, a existência de PoC pública já é motivo suficiente para tratar como prioridade de patch, independentemente de haver exploração confirmada ou não.

Atualizar o Node.js é suficiente ou preciso reconstruir minha imagem de contêiner?
Atualizar o Node.js é necessário, mas não basta trocar a versão no manifesto. Se a aplicação roda em contêiner, a imagem precisa ser reconstruída e redeployada para que a versão corrigida do runtime, com a biblioteca Brotli corrigida embutida, realmente substitua a versão vulnerável em produção. Reiniciar o contêiner sem reconstruir a imagem não resolve.

Meu servidor Node.js puro, sem Express, está vulnerável?
Depende do que a aplicação faz. Um servidor Node.js HTTP puro, sem middleware configurado, não decodifica automaticamente corpos de requisição Brotli recebidos, então esse caminho não se abre sozinho. Mas se o seu código chama node:zlib para descomprimir Brotli recebido de fora, o caminho existe do mesmo jeito. E se a aplicação usa fetch() ou outro cliente HTTP para buscar recursos externos e processa respostas comprimidas, o caminho pelo lado cliente continua exposto, independentemente de usar Express ou não.

Como sei se minha aplicação usa uma versão vulnerável do Brotli?
Não existe um comando único, mas a checagem é rápida. No Node.js, rode node --version em cada servidor e dentro de cada imagem (docker run --rm <imagem> node --version): abaixo de 22.23.4, 24.22.1 ou 26.12.1 na respectiva linha, está vulnerável. Em Python, pip show brotli brotlicffi mostra se os pacotes estão abaixo de 1.2.1 e 1.2.1.0. No .NET, dotnet --info lista os runtimes instalados para comparar com a atualização emergencial da Microsoft. Para outras aplicações que embutem o Brotli, a referência são as versões 1.0.10, 1.1.1 e 1.2.1 da biblioteca.

Facebook
Twitter
WhatsApp