Brotli CVE-2026-111497: corrija apps Node.js, Bun e Python

Brotli CVE-2026-111497: corrija apps Node.js, Bun e Python

Brotli CVE-2026-111497: corrija apps Node.js, Bun e Python

CVE-2026-111497 é um bug de corrupção de memória no decodificador Brotli do Google, o código C que descompacta dados com Content-Encoding: br. Dados comprimidos manipulados escrevem além do fim de um buffer, o que pode derrubar o programa, vazar memória ou executar o código do atacante. Node.js, Bun, os pacotes Python Brotli e brotlicffi e o Envoy trazem cada um a sua própria cópia desse decodificador, por isso cada um precisa ser atualizado separadamente. Este guia mostra quando uma aplicação está de fato exposta, como verificar um servidor com um único comando e como aplicar a correção sem esquecer nenhum contêiner.

Qual a gravidade

  • O Google dá nota 9.2 (critical) no CVSS 4.0, o Node.js classifica como high e a Red Hat como 8.1.
  • Os pesquisadores da Imperva executaram o próprio código num Node.js 24.22.0 sem patch em Linux ARM64, tanto por uma resposta obtida via fetch quanto pelo corpo de uma requisição no Express. O exploit não é público.
  • A avaliação da CISA de 23 de outubro não registrou exploração ativa, e não há prova de conceito pública confiável.
  • A falha funciona nos dois sentidos: um servidor que descompacta entradas comprimidas pode ser atacado por um cliente, e um cliente que descompacta respostas comprimidas pode ser atacado por um servidor.

A correção entrou no código-fonte do Brotli em 27 de fevereiro, mas nenhuma versão do Brotli a incluiu até 21 de outubro, e é por isso que todos os runtimes corrigidos saíram na mesma semana.

Você está exposto?

Só corre risco o código que decodifica dados Brotli controlados por outra pessoa:

  • Node.js e Bun - o fetch() nativo ao ler uma resposta enviada com Content-Encoding: br, chamadas Brotli de node:zlib sobre dados não confiáveis e parsers de corpo que descompactam uploads em Brotli (Express 5, body-parser 2). Um servidor HTTP Node.js simples não decodifica corpos de requisição por conta própria.
  • Python - basta ter o pacote Brotli ou brotlicffi instalado: requests, urllib3, httpx e aiohttp passam a decodificar respostas Brotli sozinhos, mesmo que o seu código nunca importe Brotli.
  • Envoy e Istio - apenas se houver um filtro de descompressão Brotli configurado.

Qualquer serviço que chame APIs de terceiros, webhooks, provedores de pagamento ou faça scraping de páginas executa fetch() contra servidores que você não controla. Remover br do Accept-Encoding não é uma correção: um servidor pode enviar Brotli mesmo assim.

Software Afetado Corrigido em
Node.js 22.x, 24.x, 26.x antes da correção; 20.x e anteriores (fim de vida) 22.23.4, 24.22.1, 26.12.1
Bun 1.4.3 e anteriores 1.4.4
Python Brotli 1.2.0 e anteriores 1.2.1
Python brotlicffi 1.2.0.x e anteriores 1.2.1.0
Google Brotli (biblioteca C) 1.0.3 - 1.2.0 1.0.10, 1.1.1, 1.2.1
Envoy 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
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

Verifique um servidor com um comando

Este script de shell POSIX verifica Bun, Node.js e Python na máquina (ou dentro de um contêiner) e informa quais são anteriores à correção. Salve-o como brotli-check.sh:

#!/bin/sh
# CVE-2026-111497 (Brotli decoder): which runtimes on this host are older than the fixes?
ver_lt() { [ "$1" = "$2" ] && return 1; [ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -n1)" = "$1" ]; }
if command -v bun >/dev/null 2>&1; then
  v=$(bun --version)
  if ver_lt "$v" 1.4.4; then echo "bun $v: VULNERABLE, upgrade to 1.4.4+"; else echo "bun $v: fixed"; fi
fi
if command -v node >/dev/null 2>&1; then
  v=$(node -p "process.versions.bun ? '' : process.versions.node")
  if [ -z "$v" ]; then echo "node: this is Bun's node shim, see the bun line"; else major=${v%%.*}
  case $major in
    22) fix=22.23.4 ;; 24) fix=24.22.1 ;; 26) fix=26.12.1 ;;
    *) fix= ;;
  esac
  if [ -z "$fix" ]; then echo "node $v: no fixed release for this line, move to 22, 24 or 26"
  elif ver_lt "$v" "$fix"; then echo "node $v: VULNERABLE, upgrade to $fix+"
  else echo "node $v: fixed"; fi
  fi
fi
for py in python3 python; do
  command -v $py >/dev/null 2>&1 || continue
  $py - <<'PY'
from importlib import metadata
for pkg, fix in (("Brotli", "1.2.1"), ("brotlicffi", "1.2.1.0")):
    try:
        v = metadata.version(pkg)
    except metadata.PackageNotFoundError:
        print(f"python {pkg}: not installed")
        continue
    a = [int(x) for x in v.split(".") if x.isdigit()]
    b = [int(x) for x in fix.split(".")]
    print(f"python {pkg} {v}: {'VULNERABLE, upgrade to ' + fix + '+' if a < b else 'fixed'}")
PY
  break
done
sh brotli-check.sh
docker exec my-app sh -s < brotli-check.sh   # the same check inside a running container

Saída verificada em 2026-10-24 (um notebook de desenvolvimento e depois imagens oficiais do Docker):

bun 1.4.1: VULNERABLE, upgrade to 1.4.4+
node 26.6.0: VULNERABLE, upgrade to 26.12.1+
python Brotli: not installed
python brotlicffi: not installed
bun 1.4.4: fixed
node: this is Bun's node shim, see the bun line
node 22.23.4: fixed
node 16.20.2: no fixed release for this line, move to 22, 24 or 26
python Brotli 1.1.0: VULNERABLE, upgrade to 1.2.1+
python brotlicffi: not installed

Rode-o em cada contêiner, não só no host: o Node.js do host não diz nada sobre o que vem embutido numa imagem.

Como aplicar a correção

  1. Encontre cada cópia. As imagens são o esquecimento mais comum. Liste o que está rodando: docker ps --format '{{.Image}}' e depois as linhas FROM dos seus Dockerfiles. Uma tag como node:22 ou oven/bun:alpine só avança quando você faz pull; uma tag fixada como oven/bun:1.4.1-slim nunca avança.
  2. Atualize o runtime. Suba as tags fixadas (oven/bun:1.4.4-slim, node:22.23.4-alpine), rode bun upgrade e atualize os pacotes Node.js nos hosts, e pip install -U "Brotli>=1.2.1" (ou brotlicffi>=1.2.1.0) nos ambientes Python. Se uma aplicação Python não precisa de Brotli, pip uninstall Brotli brotlicffi também fecha o caminho: os clientes HTTP voltam a usar gzip e deflate.
  3. Reconstrua e substitua. docker compose build --pull && docker compose up -d. Um processo em execução mantém o decodificador antigo até ser reiniciado, então reinicie também os serviços nos hosts.
  4. Verifique. Rode de novo o script de verificação dentro de cada contêiner (docker exec <name> bun --version é a versão rápida). Lockfiles com --frozen-lockfile podem quebrar a reconstrução depois de atualizar dependências: faça commit do lockfile atualizado junto com o package.json.
  5. Ainda não pode atualizar? Rejeite no proxy as requisições com Content-Encoding: br antes que qualquer coisa decodifique o corpo, e evite buscar dados de hosts não confiáveis. A Vercel observa que regras de firewall não cobrem as respostas que o seu próprio código busca em outros servidores - só a atualização resolve.

Para uma stack Node.js numa VM veja Servidor cloud para Node.js, para Python Servidor cloud para Python e Flask e, para imagens que se reconstroem sem problemas, Servidor cloud para Docker Swarm.

O que nós fizemos

Poucos dias após as correções, passamos para 1.4.4 todos os serviços da DCXV que rodam em Bun: as imagens base fixadas foram para tags corrigidas, e todas as imagens foram reconstruídas com um pull novo. Nossos componentes Node.js não decodificam corpos Brotli, e nossos proxies não têm descompressão Brotli. Os servidores dos clientes são geridos pelos seus donos: se você roda Node.js, Bun ou Python num servidor cloud da DCXV, execute hoje a verificação acima ou pergunte-nos sobre a administração gerenciada de servidores.

Fontes (verificadas em 2026-10-24): as versões de segurança do Node.js de outubro de 2026 (22.23.4, 24.22.1, 26.12.1), a versão Bun 1.4.4, a avaliação da CISA de 23 de outubro de 2026 e a pesquisa da Imperva.

PHP2Shell: verificar e corrigir as falhas RCE do PHP
clouddedicatedhosting

PHP2Shell: verificar e corrigir as falhas RCE do PHP

PHP2Shell (CVE-2026-109618, CVE-2026-109619) deixa um pedido sem autenticação executar código no PHP. Versões corrigidas, script testado, ajustes no php.ini e plano.

Brotli CVE-2026-111497: corrija apps Node.js, Bun e Python
cloudnetworkinginfrastructure

Brotli CVE-2026-111497: corrija apps Node.js, Bun e Python

Uma falha no decodificador Brotli (CVE-2026-111497) executa código via fetch() no Node.js e Bun ou clientes HTTP Python. Versões corrigidas, script testado e rebuild.

Como dimensionar um servidor cloud para SaaS: CPU, RAM, NVMe
cloudinfrastructurepricing

Como dimensionar um servidor cloud para SaaS: CPU, RAM, NVMe

Dimensione um servidor cloud para SaaS em Docker e Node.js: memória, limites de CPU, NVMe e cópias, teste de carga k6, preço mensal total e folha de cálculo.

Agentes de código com IA em VPS da UE: setup reforçado
aicloudhosting

Agentes de código com IA em VPS da UE: setup reforçado

Hospede agentes de código com IA num VPS da UE com limites: espaços descartáveis, saída permitida, tokens restritos, tetos, código testado, riscos e custo.

Corrigir a geolocalização IPv4 após uma transferência
ipv4networkingtransfer

Corrigir a geolocalização IPv4 após uma transferência

O seu bloco IPv4 transferido ainda mostra o país anterior? Verifique WHOIS, BGP e GeoIP, publique um geofeed e peça correções a cada fornecedor, passo a passo.