CVE-2026-41242: como corrigimos o protobufjs crítico na imagem da Evolution API

João Rangel9 de novembro de 20268 min de leitura

Neste artigo
Capa CVE-2026-41242: como corrigimos o protobufjs crítico na imagem da Evolution API

O scan diário de vulnerabilidades das nossas imagens de produção apontou uma falha crítica na imagem da Evolution API: a CVE-2026-41242, no protobufjs, com nota 9.8 no NVD. O detalhe que torna o caso interessante: a cópia principal do pacote já estava corrigida. A versão vulnerável estava escondida dentro de outra dependência, e o projeto não tem release estável nova desde a 2.3.7, de dezembro de 2025. Neste artigo mostramos como encontramos essa cópia, por que "atualizar a imagem" não era opção e o passo a passo que usamos para corrigir sem quebrar o WhatsApp.

O que é a CVE-2026-41242

O protobufjs é a implementação de Protocol Buffers mais usada no ecossistema JavaScript. A falha (CWE-94, injeção de código) acontece quando a biblioteca carrega uma definição de protobuf ou um descritor JSON montado por um atacante: nomes e referências de tipo controlados pelo esquema chegam à geração de código em tempo de execução sem validação suficiente, e isso permite executar JavaScript arbitrário no processo.

  • Severidade: crítica no NVD (CVSS 3.1: 9.8). O advisory do GitHub classifica como alta (CVSS 4.0: 8.7). A diferença vem da versão do CVSS e da avaliação de cada fonte; nas duas, é falha para corrigir.
  • Versões afetadas: pelo advisory, até a 7.5.4 e a 8.0.0. Na prática, toda a linha 6.x abaixo de 6.11.6 também.
  • Correções: 7.5.5 e 8.0.1, listadas no advisory, e 6.11.6, backport da mesma correção para a linha 6.x publicado pelos mantenedores em maio de 2026.
  • Condição para explorar: o atacante precisa controlar ou influenciar o esquema carregado pelas APIs de reflexão. Aplicações que só decodificam mensagens com esquemas próprios e confiáveis não são afetadas diretamente.

Na Evolution API o protobufjs é usado pela pilha do WhatsApp com esquemas que vêm no próprio código, então o risco prático era baixo. Mesmo assim, corrigimos: uma crítica que fica "aceita" no relatório vira ruído, e ruído é o que faz uma equipe deixar de olhar o próximo alerta, que pode ser real.

A versão vulnerável estava escondida

A primeira reação é procurar o pacote na raiz do node_modules. Lá ele estava na 7.5.5, já corrigido. O problema estava num nível abaixo:

node_modules/protobufjs                          7.5.5  (corrigido)
node_modules/libsignal/node_modules/protobufjs   6.8.8  (vulnerável)

O libsignal, usado na criptografia do WhatsApp, fixa a versão exata "protobufjs": "6.8.8" no seu package.json. Como a cópia da raiz não satisfaz essa exigência, o npm instala uma cópia própria dentro do pacote. Quem confere só a versão da raiz (npm ls protobufjs --depth=0, ou o package.json da aplicação) deixa essa cópia passar. O Trivy lê todos os package.json da imagem e por isso a encontra.

Para localizar todas as cópias de um pacote dentro de uma imagem:

docker run --rm --entrypoint sh SUA_IMAGEM -c \
  'find / -path "*/node_modules/protobufjs/package.json" 2>/dev/null | xargs grep -H "\"version\""'

Por que não bastava atualizar

O caminho natural seria esperar uma versão nova da Evolution API ou do libsignal. Nenhum dos dois tinha release estável com a correção, e uma falha crítica não deveria esperar o calendário de terceiros. Também descartamos subir o protobufjs do libsignal para a 7.x: mudar de versão principal pode alterar APIs internas e quebrar justamente a criptografia das mensagens.

A boa notícia é que a linha 6.x ganhou a 6.11.6 com a correção. Dentro da mesma versão principal, a troca é segura desde que as dependências da versão nova já existam na imagem.

Passo a passo da correção

  1. Imagem derivada, não fork. Em vez de recompilar o projeto, criamos uma camada por cima da imagem original que só troca o que precisa. Aplicação, usuário, entrypoint e comando continuam os do fornecedor, o que facilita acompanhar as próximas versões.
  2. Conferir as dependências da versão nova. Antes de trocar, comparamos as dependencies da 6.11.6 (npm view [email protected] dependencies) com o que a imagem resolve a partir da pasta do pacote. Todas já estavam lá, inclusive o long 4.x que o libsignal traz aninhado. Se faltasse alguma, a troca não seria só "copiar a pasta".
  3. Trocar no lugar. Baixamos o pacote oficial com npm pack [email protected] e substituímos a pasta aninhada, mantendo o dono dos arquivos e a node_modules interna que existia.
  4. Tirar o que não roda. O tarball da 6.11.6 traz a pasta cli/ (as ferramentas pbjs e pbts) com dependências próprias, que o Trivy passou a apontar. Em produção ninguém usa essa CLI, então ela saiu da imagem: o que não está lá não precisa ser corrigido.
  5. Aproveitar a viagem. Com o mesmo critério (mesma versão principal e nenhuma dependência nova), atualizamos outros pacotes da imagem e os pacotes do sistema operacional.
  6. Testar o que importa. Antes de publicar a imagem, subimos o container com um Postgres descartável e validamos: as migrations rodaram, a API respondeu, criamos uma instância de WhatsApp e o QR code foi gerado. O QR code é o teste que interessa aqui, porque só aparece se a conversa com os servidores do WhatsApp, que passa pelo libsignal e pelo protobufjs, funcionar.
  7. Escanear de novo. Rodamos o Trivy na mesma versão usada pelo scan diário e confirmamos que a CVE-2026-41242 saiu do relatório.
  8. Trocar com plano de volta. A imagem anterior continua no registry; voltar é um comando. Depois da troca, conferimos que as instâncias reconectaram.

E se você monta a Evolution a partir do código?

Quem faz o build da Evolution API a partir do repositório tem um caminho mais simples: forçar a versão corrigida com overrides no package.json, o que vale também para dependências aninhadas.

{
  "overrides": {
    "libsignal": {
      "protobufjs": "6.11.6"
    }
  }
}

Depois do npm install, confirme com npm ls protobufjs (que lista todas as cópias, inclusive as aninhadas) que nenhuma ficou abaixo da 6.11.6, e repita o teste do QR code antes de ir para produção. No pnpm o equivalente é a chave pnpm.overrides.

O que levamos deste caso

  • Escaneie a imagem, não só o projeto. O que roda em produção é a imagem, com tudo o que ela carrega, inclusive dependências que você nunca declarou.
  • Procure todas as cópias do pacote. A raiz do node_modules corrigida não garante nada.
  • Prefira a mesma versão principal. É o que permite corrigir sem regressão quando o fornecedor não ajuda.
  • Remova o que não é usado. Menos código na imagem é menos falha para corrigir.
  • Teste o fluxo que a dependência sustenta, não só se o container sobe.

Se você usa a Evolution API, veja também nosso guia sobre a CVE-2026-91997, que expõe o endpoint /metrics, outra falha recente do projeto, esta resolvida com configuração.

Perguntas frequentes

Minha Evolution API está vulnerável à CVE-2026-41242?

Se a imagem tem alguma cópia do protobufjs abaixo de 6.11.6 (ou da 7.x abaixo de 7.5.5), o scanner vai apontar a falha. A imagem oficial da 2.3.7 traz a 6.8.8 dentro do libsignal. O risco prático depende de um atacante conseguir influenciar os esquemas carregados, o que não é o uso normal da Evolution, mas a recomendação é corrigir.

Posso simplesmente subir o protobufjs do libsignal para a 7.x?

Não recomendamos. O libsignal fixa a 6.8.8, e mudar de versão principal pode quebrar a criptografia das mensagens. A 6.11.6 corrige a falha mantendo a mesma linha.

Atualizei para a 6.11.6 e o npm audit (ou o Dependabot) ainda acusa a falha. A correção não funcionou?

Provavelmente funcionou. Essas ferramentas leem o advisory do GitHub, que registra só as correções 7.5.5 e 8.0.1 e marca como afetado tudo até a 7.5.4. Como a 6.11.6 é um backport publicado depois, ela pode continuar sendo apontada como falso positivo. Para confirmar, verifique se a cópia instalada é mesmo a 6.11.6 (npm ls protobufjs) e confira a release da 6.11.6, que traz o backport da correção. Scanners com base própria de vulnerabilidades, como o Trivy que usamos, já reconhecem a versão como corrigida.

Preciso de uma ferramenta paga para achar dependências aninhadas?

Não. O Trivy é gratuito e de código aberto: trivy image --severity CRITICAL,HIGH SUA_IMAGEM lista as falhas com o caminho de cada pacote dentro da imagem.

Corrigir a imagem por conta própria não complica as próximas atualizações?

Complica menos do que manter um fork. Como a camada só troca pacotes por cima da imagem original, basta refazê-la sobre a versão nova quando ela sair, ou descartá-la se a versão nova já trouxer a correção.

Conclusão

A CVE-2026-41242 mostrou um ponto que vale para qualquer stack: a falha crítica nem sempre está onde você procura primeiro, e o fornecedor nem sempre vai corrigir no seu prazo. Com uma imagem derivada, troca dentro da mesma versão principal, remoção do que não é usado e um teste do fluxo real, dá para fechar a falha sem esperar o fornecedor e sem colocar a produção em risco. Para aprofundar em Docker, Node.js e segurança de aplicações, conheça os cursos da plataforma da Hcode.

Fontes

Continue aprendendo com a Hcode

Cadastre-se na plataforma de cursos e acompanhe os próximos guias do blog.