Programação Por Equipe DevBras

Capa do artigo: Falha no Brotli (CVE-2026-111497): como checar e corrigir

Falha no Brotli (CVE-2026-111497): como checar e corrigir

Falha crítica no Brotli (CVE-2026-111497) afeta Python, curl, Node, Envoy e imagens Docker. Veja como conferir, as versões corrigidas e o que fazer já.

Se você atualizou o Node.js essa semana por causa do Brotli e achou que o assunto tinha acabado, tem mais coisa. A CVE-2026-111497, que a Aikido apelidou de HTTP2Shell, está na biblioteca Brotli do Google, e não só no Node. Ela recebeu nota 9.2 (crítica) no CVSS 4.0 e pode ser explorada sem autenticação. Ela aparece em pacotes Python, no curl e no libcurl do sistema, no Envoy/Istio, no Bun e em praticamente toda imagem Docker baseada em Debian.

Resumindo: atualize a lib Brotli do sistema e os pacotes Python, reconstrua as imagens e reinicie os serviços. Abaixo está o passo a passo completo, com os comandos e as versões corrigidas de cada ecossistema.

O que é a falha CVE-2026-111497

O bug está no decodificador (c/dec/decode.c). Uma função usada na troca de blocos devolve um valor ambíguo, que pode significar "stream inválido" ou "preciso de mais dados", e o caminho rápido da descompressão ignora esse retorno. O decodificador então segue trabalhando com o estado corrompido e escreve fora dos limites da memória (CWE-787).

De acordo com o registro oficial da CVE, publicado pelo Google:

  • Versões afetadas: Brotli de 1.0.3 até 1.2.0, em todas as plataformas.
  • Impacto: um atacante remoto e não autenticado, usando um stream Brotli malicioso, pode corromper ou vazar memória, derrubar o processo (DoS) e potencialmente executar código.
  • Versões corrigidas: 1.0.10, 1.1.1 e 1.2.1, publicadas em 21/10/2026 nas releases do google/brotli.
  • Nota: CVSS 4.0 9.2 (crítica). A Red Hat classifica como Important (CVSS 3.1 8.1) e lembra que ASLR, NX e FORTIFY dificultam a execução de código.

Está sendo explorada?

Até a noite de 23/10/2026 não há exploração ativa confirmada: a CVE não está no catálogo KEV da CISA. A Red Hat diz que não existe prova de conceito pública e confiável de RCE, mas pesquisadores já demonstraram execução de código num build do Node.js 24. A correção é pública, então é questão de tempo. Não espere.

Quem está exposto

O risco aparece sempre que um programa descompacta Brotli vindo de alguém em quem você não confia. Isso acontece por dois caminhos.

Entrada: o seu servidor descompacta o corpo da requisição

São APIs que aceitam Content-Encoding: br e descompactam o corpo antes de processar. No Node, a Semgrep lista o Express 5 (body-parser), o Koa e derivados via co-body (Egg, Strapi, Adonis), o @fastify/compress e o ultimate-express. O mesmo vale para frameworks Python que descompactam o corpo da requisição.

Saída: o seu código baixa conteúdo de terceiros

São clientes HTTP que descompactam a resposta automaticamente quando o servidor manda br: o fetch() do Node, o requests/urllib3, o httpx[brotli], o aiohttp, o Scrapy e o curl/libcurl compilado com libbrotli. Os alvos clássicos são webhook, preview de link, crawler, importador de URL e integração com API externa. Se você recebe webhooks, vale revisar também como validar a assinatura deles.

Segundo a Aikido, Apache e Nginx não decodificam Brotli de requisição por padrão. Só servir conteúdo comprimido em br (compressão de saída) não é o problema; o risco está em descompactar dados de fora.

Passo 1: descubra onde o Brotli está

# Debian/Ubuntu: biblioteca do sistema (usada por curl, nodejs da distro etc.)
dpkg -l | grep -i brotli
apt-cache policy libbrotli1

# RHEL, Fedora, Alma, Rocky
rpm -qa | grep -i brotli

# Python: pacotes e quem depende deles
pip show Brotli brotlicffi
pipdeptree -r -p Brotli
grep -i brotli poetry.lock uv.lock requirements*.txt

# Runtimes
node -v
bun --version

# Dentro de cada imagem Docker que você roda
docker run --rm --entrypoint sh SUA-IMAGEM -c 'dpkg -l | grep -i brotli'

Atenção com o curl: o curl -V mostra a versão upstream da lib (por exemplo brotli/1.1.0) e continua mostrando a mesma coisa depois do patch, porque as distros aplicam a correção sem mudar esse número. Testamos num Debian 13: depois de atualizar para 1.1.0-2+deb13u1, o curl ainda exibe brotli/1.1.0. Confira sempre a versão do pacote.

Os scanners de dependência (pip-audit, Dependabot, Safety) podem ainda não acusar essa CVE, segundo a Aikido. Não confie só no painel verde.

Passo 2: versões corrigidas

  • Brotli upstream: 1.0.10, 1.1.1 ou 1.2.1 (releases).
  • Debian 12 (bookworm): brotli 1.0.9-2+deb12u1 (DLA-4855-1, anúncio).
  • Debian 13 (trixie): brotli 1.1.0-2+deb13u1 (DSA-6582-1). Status completo no Debian Security Tracker. O nodejs empacotado pelo Debian usa a lib do sistema, então atualizar a libbrotli corrige o node da distro também.
  • Ubuntu: todas as versões ainda aparecem como "Needs evaluation" no Ubuntu Security. Acompanhe e aplique a mitigação enquanto isso.
  • Red Hat: ainda sem pacote corrigido listado na página da CVE.
  • Python (PyPI): Brotli 1.2.1 e brotlicffi 1.2.1.0, conforme o advisory GHSA-9v8h-qqgm-4m35.
  • Node.js: 22.23.4, 24.22.1 e 26.12.1. Linhas em fim de vida (EOL) não recebem correção (aviso do Node.js).
  • Bun: 1.4.4 (notas da versão).
  • Istio (Envoy): 1.29.9, 1.30.6 e 1.31.2, para quem habilita descompressão Brotli, por exemplo via EnvoyFilter (ISTIO-SECURITY-2026-007).

Passo 3: atualize

# Debian (e Ubuntu, quando sair o pacote)
sudo apt-get update
sudo apt-get install --only-upgrade libbrotli1

# RHEL/Fedora (quando o pacote corrigido sair)
sudo dnf upgrade brotli

# Python: atualize e regere o lockfile
pip install -U "Brotli>=1.2.1" "brotlicffi>=1.2.1.0"
# poetry: poetry update brotli   |   uv: uv lock --upgrade-package brotli

# Node.js (exemplo com nvm) e Bun
nvm install 24.22.1
bun upgrade

Docker: reconstrua a imagem, não só o host

Atualizar o host não corrige os containers: cada imagem traz a própria libbrotli e os próprios pacotes Python. Reconstrua puxando a imagem base nova e sem cache:

docker build --pull --no-cache -t minha-app:brotli-fix .
docker compose pull && docker compose up -d --force-recreate

Se a sua imagem usa :latest como base, esse é um bom momento para fixar a versão da tag e para travar as dependências com lockfile. Quem gerencia muitos containers por um painel (Portainer, Dockge, Komodo ou o Dockyard) consegue ver de uma vez quais stacks ainda rodam imagens antigas.

Reinicie tudo

Um processo que já estava rodando continua com a biblioteca antiga carregada na memória. Reinicie os serviços, workers, filas, jobs agendados e todas as réplicas:

sudo systemctl restart SEU-SERVICO
# processos que ainda usam a versão antiga (apagada) da lib:
sudo grep -l 'libbrotli.*(deleted)' /proc/*/maps 2>/dev/null

Passo 4: mitigação enquanto não dá pra atualizar

A recomendação da Red Hat é limitar a exposição e, de preferência, não aceitar nem decodificar automaticamente Content-Encoding: br de fontes não confiáveis. Na prática:

  • Recuse corpo em Brotli antes de descompactar, respondendo 415. Exemplo para Nginx, que testamos:
server {
    # recusa corpo de requisição em Brotli (mitigação temporária)
    if ($http_content_encoding ~* "br") {
        return 415;
    }
    # ...
}
  • E um exemplo de middleware para Express, posicionado antes do body-parser:
app.use((req, res, next) => {
  const ce = String(req.headers['content-encoding'] || '').toLowerCase();
  if (/(^|,)\s*br\s*(,|$)/.test(ce)) return res.status(415).end();
  next();
});
  • Python sem patch: desinstale Brotli e brotlicffi (e extras como httpx[brotli]). Os clientes voltam a usar gzip/deflate.
  • Envoy/Istio: desative ou remova o filtro de descompressão com Brotli (por exemplo, o EnvoyFilter que o habilitou) até atualizar.
  • Clientes que buscam URL de terceiros: desative a descompressão automática ou isole esse serviço (container sem privilégio, rede restrita). Rodar o container com usuário não root reduz o estrago se alguém conseguir executar código.

O que NÃO resolve sozinho

  • Tirar br do Accept-Encoding: um servidor malicioso pode mandar br mesmo assim.
  • Desligar a compressão br no CDN ou no servidor: isso só afeta o que você envia, não o que você descompacta.
  • Confiar apenas em WAF ou em limite de tamanho: eles não cobrem todos os caminhos de decodificação.

Passo 5: confirme depois do patch

  • A versão nova do pacote aparece no host e dentro de cada imagem em produção.
  • Nenhum lockfile ainda aponta Brotli < 1.2.1 ou brotlicffi < 1.2.1.0.
  • Todos os processos foram reiniciados depois do update (confira a data de início dos serviços).
  • Os logs não mostram crash nem segfault em rotas que recebem corpo comprimido ou em workers que buscam URLs.
  • Você tem um caminho de volta caso a imagem nova quebre algo; veja como ensaiar o rollback.

Perguntas frequentes

Já atualizei o Node. Estou seguro?

Só o Node. Pacotes Python, curl/libcurl do sistema, Envoy e imagens Docker trazem cópias próprias da Brotli e precisam ser atualizados separadamente.

Meu site só serve arquivos comprimidos em br. Preciso me preocupar?

O risco está em descompactar dados vindos de fora. Comprimir as suas próprias respostas não é o problema, mas confira se a sua aplicação aceita corpo em br ou baixa conteúdo de terceiros.

O curl -V ainda mostra brotli/1.1.0. Não atualizou?

Pode ter atualizado. As distros corrigem sem mudar esse número. Confira com dpkg -l | grep brotli ou rpm -q brotli.

Uso Ubuntu e não tem pacote ainda. E agora?

Aplique a mitigação (recusar br na entrada, desligar a descompressão automática nos clientes, remover o Brotli do Python) e acompanhe a página do Ubuntu Security.

Resumo

  • A CVE-2026-111497 afeta a Brotli de 1.0.3 a 1.2.0, tem nota 9.2 e pode ser explorada sem login.
  • As versões corrigidas são Brotli 1.0.10/1.1.1/1.2.1, Debian 12/13 com os pacotes listados acima, Brotli 1.2.1 e brotlicffi 1.2.1.0 no pip, Node 22.23.4/24.22.1/26.12.1, Bun 1.4.4 e Istio 1.29.9/1.30.6/1.31.2.
  • Atualize, reconstrua as imagens, reinicie tudo e confira a versão do pacote (não a do curl -V).

Fontes oficiais: CVE.org, GitHub Advisory, Debian, Ubuntu, Red Hat, Node.js, Istio. Atualizado em 23/10/2026.

Avalie este artigo