Execute isto agora. Se a sua versão estiver abaixo do limite mínimo indicado na tabela, a vulnerabilidade de RCE no Brotli do Node.js (CVE-2026-111497) afeta você, e invasores já a estão explorando ativamente.

Experimente o Apidog hoje

node -v 
Linha de versão Vulnerável Corrigida a partir de Mais recente (5 de nov. de 2026)
26.x Abaixo de 26.12.1 26.12.1 26.13.0
24.x Abaixo de 24.22.1 24.22.1 24.22.2
22.x Abaixo de 22.23.4 22.23.4 22.23.4
25.x, 20.x e anteriores Fim da vida útil (EOL): sem patch e não avaliada Nenhuma correção disponível Migre para a 24 ou 26

Para uma confirmação adicional, consulte o próprio binário diretamente:

node -p "require('node:zlib').constants.BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH" 

A correção adicionou essa constante. Nós a executamos em nove builds oficiais para macOS das três linhas com suporte: todas as versões corrigidas exibiram -17, enquanto as versões mais antigas retornaram undefined. Priorize o node -v, pois uma distribuição Linux que faz backport do patch pode não incluir essa constante.

Ignore process.versions.brotli. O comando retornou 1.2.0 tanto na 24.21.0 quanto na 24.22.1, e 1.1.0 tanto na 22.23.3 quanto na 22.23.4. O Node.js aplicou a correção via cherry-pick sem alterar a versão informada da biblioteca, portanto esse campo não serve para confirmar se o patch foi aplicado.

TL;DR

Pergunta Resposta
Do que se trata? Gravação fora dos limites (out-of-bounds write) no decodificador Brotli integrado ao Node.js, também conhecida como Node2Shell ou HTTP2Shell
Impacto Travamento (crash), vazamento de memória ou execução remota de código (RCE)
Severidade ALTA segundo o Node.js; 9.8 CRÍTICA (CVSS 3.1) segundo o NVD
Está sendo explorada? Sim. O catálogo CISA KEV a incluiu em 27 de outubro de 2026
Requer autenticação? Não, de acordo com o vetor do NVD e a análise da Akamai
Quem pode ser atingido? Aplicações que decodificam dados Brotli não confiáveis: corpos de requisições no Express 5, respostas de fetch(), chamadas diretas a node:zlib
Correção Atualizar o runtime, reconstruir as imagens e reiniciar os processos
Existe solução paliativa? O comunicado oficial não lista nenhuma. As medidas temporárias descritas abaixo reduzem a exposição, mas não cobrem todos os cenários

Linha do tempo da CVE-2026-111497: correções do Node.js em 21 de outubro, CVE publicada em 22 de outubro, tráfego de exploração registrado em 26 de outubro, inclusão no CISA KEV em 27 de outubro, prazo do KEV em 10 de novembro, próximo lançamento de segurança do Node.js em 11 de novembro

A ELLIO identificou tráfego de exploração em seus sensores em 26 de outubro, cinco dias após a liberação da correção. O payload capturado tinha como alvo o Node.js 24.22.0 em arquitetura x86-64. O estágio final desse payload falhou nos testes da ELLIO, mas a própria empresa confirmou a execução de código em compilações padrão da versão 24.22.0. A CISA estabeleceu o prazo de 10 de novembro para que as agências federais dos EUA tomem providências e classifica o uso por ransomware como “Desconhecido”. A telemetria da Akamai apontou que 61% das redes ainda executavam versões afetadas em 26 de outubro.

Entenda a Node2Shell: como funciona a falha no Brotli

A Node2Shell é uma vulnerabilidade de gravação fora dos limites (out-of-bounds write) no decodificador Brotli integrado ao runtime do Node.js. Um fluxo compactado malformado faz com que o decodificador grave além do limite de um buffer interno de oito bytes, corrompendo a memória do processo. As consequências podem variar entre travamentos do sistema, vazamento de memória ou a execução de código malicioso controlado pelo invasor diretamente no seu servidor.

A causa raiz é a classificação incorreta de um erro. Uma troca de bloco inválida era interpretada como “preciso de mais dados de entrada” em vez de “estes dados estão corrompidos”, fazendo com que o decodificador de streaming continuasse adicionando bytes àquele buffer reduzido.

A falha reside na biblioteca Brotli da Google, nas versões de 1.0.3 a 1.2.0, portanto não se trata de um problema exclusivo do Node.js. O projeto Node.js corrigiu sua cópia aplicando o commit upstream 0ed4268a via cherry-pick na versão 24.22.1 e em suas ramificações correspondentes. Os pesquisadores de segurança da OpenAI Codex, Khai Tran e Sylvie Mayer, foram os responsáveis por reportar a vulnerabilidade.

Seus scanners de dependências não vão detectar essa brecha, pois o decodificador faz parte do próprio runtime, e não de um pacote de dependência. O comando npm install informou 0 vulnerabilidades em nosso projeto de teste com Express 5 executado sobre um Node.js 24.15.0 desatualizado.

Quem está vulnerável

Estar em um runtime vulnerável é apenas metade da equação. A outra metade é a existência de um caminho que entregue dados Brotli não confiáveis ao decodificador. Testamos cada cenário no Node.js 24.22.1 enviando um corpo inválido e inofensivo (o texto not-valid-brotli) com o cabeçalho Content-Encoding: br, além de fornecer Brotli válido para cada cliente.

Caminho Versão testada Executa o decodificador? O que observamos
Express 5 express.json() 5.3.0 (body-parser 2.4.0) Sim, por padrão 400, “Decompression failed”
Express 4 express.json() 4.22.3 (body-parser 1.20.9) Não 415, codificação incompatível
Koa @koa/bodyparser 6.1.0 Sim, por padrão 500, erro de BrotliDecoder no log
Fastify com @fastify/compress 9.3.0 Sim, após o registro 400, FST_CP_ERR_INVALID_CONTENT
Fastify padrão (sem plugins) 5.12.8 Não 400, JSON inválido
Servidor node:http nativo ou http.get 24.22.1 Não Os bytes brutos passam direto
fetch() nativo 24.22.1 Sim, sempre Decodificou a resposta
axios, got, node-fetch 1.21.0, 16.2.0, 3.3.2 Sim, por padrão Decodificou a resposta
zlib.brotliDecompress*, createBrotliDecompress Qualquer uma Sim Esta é a própria API do decodificador

Diagrama das vias de entrada para o decodificador Brotli em node:zlib: parsers do Express 5, parsers de corpo do Koa e Fastify com @fastify/compress no fluxo de entrada; fetch, axios e got no fluxo de saída; enquanto Express 4, Fastify puro e node:http nativo não acionam o decodificador

Dois resultados chamam a atenção. O fetch() decodificou o Brotli mesmo quando a requisição especificava Accept-Encoding: identity, pois ele segue o cabeçalho retornado na resposta, e não o que foi solicitado. Qualquer servidor externo requisitado pela sua aplicação pode acionar o decodificador; portanto, recursos como testadores de webhook, geradores de prévia de links ou importadores de URL estão expostos. Além disso, um status 400 por si só não comprova proteção: tanto o Express 5 quanto o Fastify padrão retornam 400, mas somente o Express 5 chegou a executar o decodificador. Analise com atenção a mensagem de erro.

Identifique esses caminhos com três comandos:

# Direct decoder use grep -rnE "brotliDecompress|createBrotliDecompress" src/ # Parsers that decode request bodies npm ls express body-parser @koa/bodyparser @fastify/compress # Base images and pinned versions grep -rnE "^FROM .*node" --include='Dockerfile*' . 

Uma única nova chamada com fetch() muda todo esse cenário; portanto, “não acessível no momento” ainda significa que você precisa aplicar o patch.

Como corrigir a CVE-2026-111497

Atualize para a build mais recente da sua versão, e não apenas para o piso mínimo corrigido. Todas as fontes a seguir já disponibilizavam compilações corrigidas em 5 de novembro:

Método de instalação O que fazer
nvm nvm install 24 && nvm alias default 24
Homebrew brew upgrade node (ou node@24, node@22)
Docker FROM node:24.22.2-slim e, em seguida, docker build --pull
Pacotes de distribuições Linux Siga o comunicado de segurança da sua distribuição, já que ela pode disponibilizar o backport da correção sob um número de versão anterior
CI Atualize o .nvmrc, o campo engines e o node-version, e execute um novo build
Serverless Registre o process.version no log de uma função implantada; não presuma que o provedor atualizou o ambiente automaticamente

Em seguida, elimine duas armadilhas bastante comuns:

  • Reinicie tudo. Um processo em execução mantém o binário antigo carregado na memória; portanto, atualizar os arquivos em disco não surte efeito até que o pm2, o systemd ou seu orquestrador reinicie o processo.
  • Reconstrua as imagens implantadas. Imagens antigas mantêm o runtime desatualizado, e imagens fixadas por digest precisam passar por um scanner de imagens, pois a tag não indicará se estão vulneráveis.

Para concluir, execute as verificações indicadas no início deste artigo dentro do contêiner em produção, depois nos runners de CI e nas máquinas de desenvolvimento. Para consultar a versão de segurança mais recente de cada linha:

curl -s https://nodejs.org/dist/index.json | jq -r '[.[] | select(.security == true and (.version | test("^v(22|24|26)\\")))] | group_by(.version | split(".")[0]) | .[] | max_by(.date) | "\(.version) \(.date)"' 

Ainda está usando a versão 20 ou 25? Não existe nenhuma versão corrigida para elas. Leia sobre o plano de fim de vida útil (End-of-Life) do Node.js 20 e migre o quanto antes.

Mitigações para a falha do Brotli no Node.js se você não puder aplicar o patch hoje

Estas medidas servem apenas para ganhar tempo. Nenhuma delas substitui a atualização.

  1. Rejeite o br na borda (edge). Bloqueie o cabeçalho Content-Encoding: br no seu proxy reverso ou balanceador de carga, com correspondência case-insensitive e considerando listas como gzip, br.
  2. Rejeite-o na própria aplicação. Insira esta verificação antes dos seus parsers de corpo de requisição. Em nosso teste com Express 5, ela retornou 415:
app.use((req, res, next) => { const encoding = req.headers['content-encoding'] || ''; if (/\bbr\b/i.test(encoding)) return res.status(415).end(); next(); }); 
  1. Desative a descompactação (inflation). A opção express.json({ inflate: false }) retornou 415 para a mesma requisição. Ela também rejeita requisições compactadas com gzip, portanto verifique a compatibilidade dos seus clientes antes.
  2. Controle respostas externas (outbound). O axios aceita decompress: false, o que manteve os bytes sem decodificação em nosso teste. O fetch() nativo não possui um mecanismo padrão de desativação; por isso, restrinja quais hosts ele pode acessar usando listas de permissão (allowlists) e regras de controle de saída de rede (egress).
  3. Limite o raio de impacto (blast radius). Segmente os serviços Node.js e restrinja quem pode ler core dumps, já que a ELLIO destaca que travamentos podem expor dados da memória nesses arquivos.

Fique atento aos primeiros indícios observados pela ELLIO: picos repentinos de requisições com corpos codificados em Brotli com o intuito de mapear quais servidores realizam a decodificação. Um tráfego inesperado com Content-Encoding: br em uma API JSON ou um aumento incomum nas falhas e quedas de workers justificam uma investigação imediata.

Garanta que sua API resistiu ao upgrade: deixe seu agente executá-lo

Mudar a versão do runtime pode alterar o comportamento de TLS, DNS e HTTP — e a atualização de outubro mexeu nos três. Não compare essas diferenças manualmente. Permita que seu agente de desenvolvimento execute a CLI do Apidog antes e depois do processo para relatar qualquer discrepância.

npm install -g apidog-cli@latest apidog login --with-token <YOUR_TOKEN> npx -y skills add https://apidog.com # pick your agent when prompted 

Forneça um único prompt ao seu agente:

Run Apidog test suite <id> in project <id> against staging and save the results to reports/before. After I upgrade Node.js, add a test case for POST /orders that sends the plain text "not-valid-brotli" with Content-Encoding: br, asserts a 4xx status, then checks GET /health returns 200. Rerun the suite to reports/after and list every request whose result changed. 

O agente executa os seguintes comandos:

apidog run --test-suite <id> --project <id> -e <envId> -r cli,junit --out-dir reports/before apidog cli-schema get test-case-create apidog cli-schema validate test-case-create --file case.json apidog test-case create --project <id> --file case.json apidog run --test-case <caseId> --project <id> -e <envId> -r cli,json apidog run --test-suite <id> --project <id> -e <envId> -r cli,junit --out-dir reports/after 

Esse caso de teste adicional funciona como um health check, não como um exploit: o corpo da requisição é texto puro e falhou com o mesmo erro de preenchimento (padding) tanto nas compilações vulneráveis quanto nas corrigidas durante os nossos testes. Ainda assim, ele identifica uma falha real. Nosso teste com Koa respondeu com status 500 porque o erro de decodificação não foi tratado, quando uma API pública deveria retornar um status 4xx. Execute o teste apenas no ambiente de staging.

A referência do comando run detalha todas as flags disponíveis, e o guia de CI/CD mostra como integrar a mesma execução JUnit à sua esteira de automação. O plano gratuito do Apidog atende até 4 usuários.

Por que o dia 11 de novembro é importante

O projeto Node.js já pré-anunciou uma nova rodada de atualizações para as linhas 26.x, 24.x e 22.x prevista para 11 de novembro de 2026 (ou logo após), novamente com nível de severidade ALTO. Nenhuma CVE foi divulgada publicamente até o momento. Nosso guia sobre a atualização de novembro explica como se preparar.

Aplique a correção do Brotli agora em vez de aguardar essa próxima janela. A vulnerabilidade já tem detalhes públicos e tráfego real de exploração hoje, e o processo de atualização realizado nesta semana servirá como ensaio para o próximo: o mesmo inventário, as mesmas reconstruções de imagens e a mesma bateria de testes. Casos como o PHP2Shell e o React2Shell seguiram essa mesma dinâmica.

Perguntas frequentes

A CVE-2026-111497 está sendo explorada ativamente? Sim. A CISA adicionou a falha ao catálogo de vulnerabilidades exploradas conhecidas (KEV) em 27 de outubro de 2026, categorizada sob Google Brotli, e a ELLIO registrou tráfego de ataques já em 26 de outubro.

A gravidade é alta ou crítica? Ambas as classificações são válidas. O Node.js a classifica como ALTA. O NVD atribui a ela pontuação 9.8 CRÍTICA no CVSS 3.1, enquanto a avaliação CVSS 4.0 emitida pelo Google é 9.2. Planeje suas ações considerando o fato de que a vulnerabilidade já está sendo explorada no mundo real.

Uso o Express 4. Estou seguro? O corpo das requisições recebidas não chega até o decodificador, mas chamadas feitas com fetch(), axios e o uso direto do módulo node:zlib continuam expostos. Além disso, essa mesma versão corrigiu outras nove CVEs, portanto faça o upgrade de qualquer maneira.

O Node.js 20 é afetado? O projeto Node.js não avalia versões que atingiram o fim da vida útil (EOL) e elas não recebem correções. Trate as linhas 20.x e 25.x como vulneráveis e não avaliadas, e faça a migração imediatamente.

Essa falha afeta outras tecnologias além do Node.js? Sim. O comunicado do GitHub abrange os pacotes brotli e brotlicffi do PyPI, e outros mantenedores relataram correções para o Bun 1.4.4 e para o .NET. Atualize cada decodificador separadamente, pois a atualização do Node.js protege apenas a cópia interna dele.