ΦFidalgo IT Solutions

Supply chain no NPM: quando a dependência vira superfície de ataque

Ataques recentes mostram que o risco deixou de estar apenas no pacote malicioso e passou a envolver CI/CD, tokens, IDEs, agentes de IA e o processo inteiro de desenvolvimento.

Fidalgo IT Solutions

Software moderno é construído sobre camadas de dependências. Um produto web comum pode depender de centenas ou milhares de pacotes diretos e transitivos, scripts de instalação, pipelines de CI/CD, actions de terceiros, extensões de IDE, tokens de publicação, credenciais de cloud e automações que rodam sem intervenção humana.

Durante muito tempo, o risco de supply chain no NPM era tratado como algo relativamente conhecido: typosquatting, pacotes falsos, dependências abandonadas ou maintainer accounts comprometidas. Esse risco continua existindo. Mas os incidentes recentes mostram uma mudança mais séria: o alvo não é mais apenas o pacote. O alvo agora é o processo de desenvolvimento.

O caso TanStack, dentro da campanha conhecida como Mini Shai-Hulud, deixou isso claro. Em 11 de maio de 2026, foram publicadas 84 versões maliciosas em 42 pacotes @tanstack/*. Segundo o postmortem oficial, o ataque combinou o padrão perigoso de pull_request_target, envenenamento de cache no GitHub Actions e extração de token OIDC da memória do runner.

O detalhe mais importante é que não foi um simples roubo de token NPM. O workflow formal de publicação também não foi diretamente comprometido. O ataque passou por dentro de uma cadeia de confiança que parecia legítima.

Essa diferença muda a forma como empresas precisam pensar sobre segurança.

O que está acontecendo

A campanha Mini Shai-Hulud afetou pacotes conhecidos nos ecossistemas NPM e PyPI, incluindo projetos ligados a TanStack, Mistral AI, UiPath e OpenSearch. O malware foi desenhado para roubar tokens GitHub e NPM, segredos de CI/CD, credenciais de cloud, chaves de API e outros dados sensíveis de ambientes de desenvolvimento.

O risco não fica restrito ao computador do desenvolvedor. Se o ambiente comprometido tem permissão para publicar pacotes, acessar repositórios internos ou executar pipelines, o malware pode se propagar lateralmente pela organização e pelo ecossistema open source.

A análise técnica da StepSecurity destacou o caráter autorreplicante da campanha: um ambiente comprometido pode virar ponto de redistribuição de novos pacotes maliciosos.

No caso TanStack, o malware podia ser ativado durante comandos como NPM install, PNPM install ou yarn install contra versões afetadas. O script malicioso buscava credenciais em locais comuns, incluindo metadados de AWS e GCP, tokens Kubernetes, Vault, .NPMrc, GitHub CLI, .git-credentials e chaves SSH.

A resposta pública da OpenAI ao incidente também mostra a extensão prática do problema. A empresa informou que dois dispositivos corporativos foram impactados por uma biblioteca open source comum ligada ao ataque TanStack, sem evidência observada de impacto a dados de clientes, sistemas de produção ou propriedade intelectual central, mas com rotação de credenciais e contenção operacional.

O ponto para empresas menores é direto: mesmo organizações maduras podem ser atingidas quando uma dependência confiável vira vetor de ataque. A diferença está na velocidade de detecção, contenção e resposta.

O problema não é usar open source

Open source não é o problema. O problema é consumir open source sem governança, sem inventário, sem isolamento e sem processo de resposta.

A discussão levantada por Mitchell Hashimoto sobre dependências e supply chain resume uma reação que vem ganhando força entre engenheiros experientes: reduzir dependências desnecessárias, questionar atualizações automáticas e tratar bibliotecas críticas como decisões de arquitetura, não como detalhes invisíveis de implementação.

Em outro ponto da discussão, Mitchell relaciona supply chain com a sustentabilidade do ecossistema open source. Esse é um aspecto estrutural: empresas dependem de maintainers que muitas vezes trabalham sozinhos, com pouco apoio financeiro, operacional ou de segurança, enquanto seus pacotes sustentam produtos comerciais inteiros.

Isso não significa que toda empresa deve forkar todas as dependências. Essa postura cria custo de manutenção, risco de perder patches de segurança e divergência em relação ao upstream.

A provocação correta é outra: dependência crítica não pode ser tratada como commodity invisível.

A pergunta não é apenas “devemos atualizar sempre?” ou “devemos congelar tudo?”. A pergunta é:

  • quais dependências são críticas;
  • quem é responsável por elas;
  • como atualizamos;
  • como testamos;
  • como bloqueamos uma versão suspeita;
  • como respondemos se um pacote já foi instalado em ambiente sensível.

Ferramentas como Socket Firewall ajudam, mas não resolvem sozinhas

A Socket lançou o Socket Firewall como uma camada gratuita para bloquear pacotes maliciosos no momento da instalação. A ferramenta funciona como um wrapper para comandos de package managers e cobre JavaScript/TypeScript com NPM, yarn e PNPM, Python com pip e uv, e Rust com cargo.

Na prática, o desenvolvedor passa a executar comandos como:

sfw NPM install
sfw PNPM install
sfw pip install
sfw cargo fetch

Por baixo, o sfw sobe um proxy HTTP efêmero, intercepta o tráfego do subprocesso e consulta a API da Socket antes que o artefato seja baixado, extraído e instalado.

Isso é relevante porque o bloqueio acontece antes da execução do pacote, não apenas depois, em uma análise tardia.

Mas há limitações importantes. A própria Socket explica que, se o artefato já estiver em cache local, talvez não exista uma nova requisição de rede para o Socket Firewall bloquear. A recomendação é limpar o cache do package manager antes de começar a usar a ferramenta.

A versão gratuita também não suporta registries customizados, não bloqueia versões desconhecidas ou ainda não escaneadas e não oferece allow-list configurável. Ferramentas desse tipo são uma boa camada defensiva, especialmente em máquinas de desenvolvimento e CI, mas não devem ser a única defesa.

A análise da Socket sobre o compromisso dos pacotes TanStack reforça outro ponto importante: provenance, OIDC e trusted publishing ajudam, mas não devem ser interpretados como garantia absoluta de segurança quando o runner confiável passa a executar código malicioso.

O que empresas deveriam fazer agora

O primeiro passo é tratar instalação de dependências como execução de código.

Scripts de lifecycle, dependências Git-based, binários nativos, extensões de IDE e CLIs internos podem executar código com acesso ao filesystem, variáveis de ambiente, tokens e credenciais locais.

1. Use lockfiles e builds reproduzíveis

Evite instalar versões flutuantes em CI e produção.

Use NPM ci, PNPM install --frozen-lockfile ou equivalente.

Lockfile não elimina supply chain attack, mas reduz a chance de um deploy puxar automaticamente uma versão recém-publicada e ainda pouco observada.

2. Crie uma janela de quarentena para updates

Quando possível, configure idade mínima de release antes de aceitar novas versões.

A ideia é simples: não instalar automaticamente um pacote publicado há poucos minutos. Muitos ataques são detectados nas primeiras horas, e essa janela pode impedir que sua empresa esteja entre as primeiras vítimas.

3. Não rode updates automáticos direto em produção

Ferramentas como Renovate e Dependabot são úteis, mas devem abrir PRs com contexto, testes e revisão.

Para dependências críticas, vale exigir revisão humana, changelog, diff do pacote publicado e validação do comportamento em ambiente isolado.

4. Revise dependências críticas e transitivas

Nem toda dependência tem o mesmo peso.

Bibliotecas usadas em build, autenticação, criptografia, deploy, infraestrutura, observabilidade e SDKs de cloud merecem tratamento especial.

Em alguns casos, faz sentido usar fork interno, mirror privado ou uma versão reduzida ao caso de uso real.

5. Desabilite scripts de instalação quando possível

postinstall, prepare e outros scripts de lifecycle são vetores frequentes.

Desabilitar scripts globalmente pode quebrar alguns pacotes, então a decisão precisa ser testada. Uma abordagem mais prática é bloquear por padrão em ambientes sensíveis e permitir exceções explícitas.

6. Separe workflows confiáveis de workflows não confiáveis

Evite rodar código de pull requests externos em workflows com permissões elevadas.

O postmortem do TanStack mostrou como pull_request_target, cache compartilhado e id-token: write podem se combinar em uma cadeia de ataque.

Workflows de release precisam ser isolados, mínimos e revisados como parte da superfície de segurança.

7. Reduza permissões de CI/CD

Configure permissões mínimas por job.

Não deixe id-token: write, secrets de cloud, tokens NPM ou GitHub PATs disponíveis para jobs que não precisam deles.

Prefira credenciais curtas, escopadas e emitidas apenas no momento necessário.

8. Não confie apenas em provenance

Trusted publishing, OIDC e Sigstore são avanços importantes.

Mas um pacote ainda pode ser publicado por um caminho aparentemente legítimo se o runner confiável executar código malicioso antes do publish.

Provenance é um sinal útil. Não é um substituto para isolamento, revisão de workflows, controle de permissões e monitoramento de publicações.

9. Controle extensões de IDE e ferramentas locais

O ambiente do desenvolvedor virou parte do perímetro.

Extensões de VS Code, agentes de IA, CLIs, plugins e ferramentas de produtividade podem acessar arquivos, terminais e credenciais.

Empresas deveriam manter uma allow-list de extensões, revisar auto-update e monitorar alterações em diretórios sensíveis.

10. Tenha inventário e plano de resposta

Em um incidente de supply chain, a empresa precisa responder rápido a perguntas básicas:

  • Quais repositórios usam o pacote afetado?
  • Qual versão está no lockfile?
  • Algum runner de CI instalou a versão maliciosa?
  • Quais secrets estavam disponíveis naquele ambiente?
  • Algum pacote interno foi publicado depois da infecção?
  • Quais caches precisam ser limpos?
  • Quais credenciais precisam ser rotacionadas?

Sem inventário, logs e ownership claro, a resposta vira adivinhação.

Um playbook mínimo de resposta

Se sua empresa instalou uma versão afetada por um ataque desse tipo, não basta reverter o pacote.

O procedimento mínimo deveria ser:

  1. Identificar todos os ambientes que instalaram a versão afetada.
  2. Isolar os hosts potencialmente comprometidos.
  3. Limpar caches de package managers e caches de CI/CD.
  4. Rotacionar todos os secrets acessíveis a partir desses ambientes.
  5. Revisar logs de publish em NPM, GitHub Packages, PyPI ou registries internos.
  6. Revisar commits recentes, especialmente commits automatizados ou incomuns.
  7. Recriar artefatos de build a partir de ambiente limpo.
  8. Validar integridade de lockfiles e hashes.
  9. Documentar o incidente e atualizar controles para evitar repetição.

A recomendação de rotacionar credenciais não é exagero. No caso TanStack, o próprio projeto recomendou rotação de credenciais AWS, GCP, Kubernetes, Vault, GitHub, NPM e SSH acessíveis a partir do host que instalou versões afetadas.

A decisão técnica também é uma decisão de negócio

Ataques de supply chain são difíceis porque exploram uma tensão real: empresas precisam entregar rápido, mas dependem de código, ferramentas e automações que não controlam completamente.

A resposta não é parar de usar open source.

Também não é adicionar mais uma ferramenta de scanner e considerar o problema resolvido.

A resposta é maturidade operacional:

  • menos dependências desnecessárias;
  • atualização com critério;
  • CI/CD com fronteiras claras;
  • credenciais curtas e escopadas;
  • máquinas de desenvolvimento tratadas como ambiente sensível;
  • monitoramento de publicações e artefatos;
  • processo de resposta testado;
  • ownership técnico sobre decisões de arquitetura.

Supply chain security é parte da engenharia de software. Não é apenas assunto de segurança.

Como a Fidalgo IT Solutions pode ajudar

A Fidalgo IT Solutions atua como prestadora de serviço técnico individual para empresas que precisam construir, operar ou melhorar sistemas em produção com menos improviso e mais controle técnico.

O serviço pode ajudar sua empresa a revisar dependências, arquitetura de CI/CD, permissões de GitHub Actions, uso de tokens, pipelines de deploy, configuração de cloud, secrets, ambientes de build, observabilidade e riscos em sistemas legados.

Também é possível estruturar um plano prático de redução de risco:

  • inventário de dependências;
  • política de atualização;
  • hardening de pipelines;
  • revisão de AWS e CI/CD;
  • resposta a incidentes;
  • recomendações para uso seguro de ferramentas open source, IDEs, agentes de IA e automações internas.

Se sua empresa depende de software para operar, vender, atender clientes ou escalar processos, vale revisar agora como esse software é construído e entregue.