Sua stack usa Brotli e você provavelmente não sabe — o que o HTTP2Shell ensina sobre dependências invisíveis
A CVE-2026-111497 — apelidada de HTTP2Shell — é uma falha crítica (9.2/10) na Brotli, a biblioteca de compressão que está em praticamente toda a web. Node.js, Python e .NET afetados de uma vez, e a CISA confirmou exploração ativa.
Mas este artigo não é sobre a CVE. É sobre a pergunta que ela escancarou e que quase nenhum time sabe responder:
Você sabe se a sua aplicação usa Brotli?
A maioria descobre que sim — do pior jeito. Porque a Brotli quase nunca aparece no package.json, no requirements.txt ou no .csproj. Ela entra como dependência da dependência: o framework HTTP puxa, o cliente de rede puxa, o runtime embute. Invisível no inventário.
O problema real: atualizar só resolve se você souber onde a falha mora
Quando sai uma CVE crítica, a corrida é "aplicar o patch". Mas patch pressupõe três respostas que o time precisa ter antes do incidente:
- Onde isso roda? Quais serviços, quais versões, qual exposição (borda pública ou job interno)?
- Quem puxa isso? Direto ou transitivo? Se é transitivo, qual dependência direta precisa subir de versão?
- O que me avisa? Se a resposta é "o noticiário", o processo já falhou.
No caso da Brotli, os patches existiam: Microsoft, Google, Node e Python publicaram correções rápido. O que separa quem resolveu em horas de quem vai descobrir pelo incidente não é ferramenta — é processo de inventário.
Como responder "onde mora?" na prática
Para enxergar a árvore transitiva da sua stack, hoje, sem instalar nada:
# Node
npm ls brotli --all # ou: npm ls zlib (bindings nativos ficam no core)
# Python
pip install pipdeptree && pipdeptree --reverse --packages brotli
# .NET
dotnet list package --include-transitive | grep -i brotli
Atenção ao detalhe cruel do caso: parte do risco não está nem em pacote instalável, mas em binding nativo embutido no runtime (o zlib/brotli do próprio Node, por exemplo). Ou seja: a correção pode ser subir a versão do runtime, não de um pacote. Inventário que só olha o lockfile não enxerga isso.
O mínimo viável de gestão de dependências
Não precisa de plataforma cara para sair do zero:
- SBOM gerado no CI (Syft, CycloneDX,
npm sbom): um artefato por build dizendo o que entrou. Quando a próxima CVE sair, a pergunta "onde mora?" vira umgrep. - Lockfile sempre commitado e builds reproduzíveis — sem isso, o SBOM mente.
- Renovate/Dependabot com janela de atualização regular. Atualização adiada é porta aberta com hora marcada — foi exatamente assim que dezenas de lojas brasileiras acabaram com skimmer no checkout semanas atrás (a correção existia havia 5 meses).
- Priorização por exposição: CVE crítica em serviço de borda pública ≠ mesma CVE num worker interno. Severidade sem contexto gera fila infinita; contexto gera decisão.
A lição
Segurança não é evento, é processo: inventário contínuo, monitoramento e capacidade de resposta. A próxima Brotli vai sair — a única escolha é descobrir pelo seu pipeline ou pelo seu incidente.
Pergunta para a comunidade: seu time consegue responder "onde roda a lib X?" em menos de 10 minutos? Como vocês resolveram — SBOM, scanner, planilha na raça?
Escrevo a série segurança sem hype — o golpe do momento explicado antes de você cair nele.