Alerta de Segurança no npm, PyPI e NuGet: Como Pacotes Maliciosos Estão Roubando Tokens, Credenciais e Segredos de Desenvolvedores

Published on: 2026-05-31
Post image
pt seguranca-npm pacotes-maliciosos-npm ataque-supply-chain-npm seguranca-de-dependencias pacotes-comprometidos-npm npm-malware roubo-de-tokens-npm roubo-de-credenciais-de-desenvolvedores seguranca-pypi seguranca-nuget pacotes-maliciosos-pypi npm

O ecossistema de pacotes JavaScript passou por uma sequência de ataques de cadeia de suprimentos que mudou a forma como projetos precisam tratar dependências. O npm, usado para distribuir bibliotecas JavaScript e Node.js, foi o principal foco porque pacotes legítimos e populares chegaram a receber versões maliciosas, publicadas por contas comprometidas, tokens roubados ou pipelines de publicação abusados.

O problema não se limita ao npm. O PyPI, repositório de pacotes Python, e o NuGet, repositório de pacotes .NET, também tiveram campanhas relevantes. Ainda assim, o caso do npm merece atenção maior porque combina volume enorme de dependências, instalação automática em ambientes de desenvolvimento, execução de scripts durante o install, dependências transitivas e uso intenso em pipelines de integração contínua e entrega contínua, conhecidos como CI/CD.

Resumo executivo do alerta

O ponto mais importante é que muitos incidentes recentes não foram simples casos de pacotes falsos. Em vários episódios, o pacote tinha nome legítimo, histórico real, milhares ou milhões de downloads e era mantido por pessoas ou organizações conhecidas. O invasor entrava por uma conta de mantenedor, por um token de publicação, por um fluxo de CI/CD ou por uma etapa de build, e publicava uma versão aparentemente normal no registro.

Esse tipo de ataque é perigoso porque o desenvolvedor costuma confiar no nome do pacote. Um projeto pode instalar uma versão comprometida sem perceber, especialmente quando usa intervalos de versão como ^1.2.3. Também existe risco quando a dependência entra de forma indireta, chamada de dependência transitiva, que é uma biblioteca instalada por outra biblioteca.

Os ataques analisados tinham objetivos parecidos. A maior parte buscava roubar credenciais de desenvolvedores e de ambientes de automação. Entre os dados visados estavam tokens npm, tokens GitHub, chaves AWS, chaves GCP, chaves Azure, secrets de CI/CD, chaves SSH, arquivos de ambiente, credenciais de deploy, dados de carteiras cripto e permissões de publicação em outros pacotes.

As fontes pesquisadas apontam para quatro ideias centrais sobre proteção. A instalação de dependências precisa ser tratada como execução de código. Scripts automáticos de instalação precisam ser controlados. Segredos não devem estar disponíveis durante a etapa de install. Ambientes de build precisam ser isolados, monitorados e capazes de bloquear conexões inesperadas.

O que significa ataque de cadeia de suprimentos de software

Cadeia de suprimentos de software é o conjunto de ferramentas, bibliotecas, pacotes, registros, pipelines, contas, scripts e serviços usados para criar uma aplicação. Um projeto moderno raramente é escrito do zero. Ele depende de centenas ou milhares de componentes externos, e cada componente pode virar uma porta de entrada.

Um ataque de cadeia de suprimentos acontece quando o invasor não ataca diretamente a aplicação final. Ele ataca algo que a aplicação confia. Isso pode ser um pacote npm, um pacote PyPI, um pacote NuGet, uma GitHub Action, uma extensão de editor, um script de build, um token de publicação ou uma conta de mantenedor.

No contexto de pacotes, o ataque costuma seguir uma lógica simples. Primeiro, o invasor publica ou altera um pacote. Depois, o pacote é instalado por um projeto real. Durante a instalação, durante o build ou durante a importação da biblioteca, o código malicioso roda com as permissões do ambiente. Se o ambiente tiver segredos disponíveis, esses segredos podem ser copiados.

Essa dinâmica explica por que ataques contra npm, PyPI e NuGet são tão graves. Eles atingem desenvolvedores, servidores de build e empresas antes mesmo de o código chegar ao usuário final. Em muitos casos, o ambiente de build possui permissões mais perigosas do que a aplicação em produção, porque contém tokens de publicação, chaves cloud e secrets internos.

Por que o npm foi o mais afetado

O npm é especialmente sensível por causa do tamanho do ecossistema JavaScript. Projetos web costumam depender de muitas bibliotecas pequenas. Uma aplicação comum pode ter poucas dependências diretas no package.json, mas centenas ou milhares de dependências indiretas no lockfile.

Essa estrutura aumenta a superfície de ataque. Um pacote pequeno, usado por muitos pacotes maiores, pode chegar a milhões de projetos sem aparecer claramente no arquivo principal do projeto. O desenvolvedor pode nunca ter escolhido aquele pacote diretamente, mas ainda assim ele entra na árvore de dependências.

Outro ponto crítico é a execução de scripts de ciclo de vida. No npm, pacotes podem declarar scripts como preinstall, install, postinstall e prepare. Esses scripts podem rodar durante a instalação. Esse comportamento existe para compilar dependências nativas e preparar bibliotecas, mas também cria uma oportunidade para execução automática de código malicioso.

O npm também é muito usado em CI/CD. Um pipeline de CI/CD é um processo automatizado que instala dependências, roda testes, gera build, publica pacotes e faz deploy. Se um pacote malicioso roda dentro desse ambiente, ele pode encontrar tokens que normalmente não existem em uma máquina comum.

Pacote falso, pacote comprometido e pacote transitivo

Existem três categorias principais que ajudam a entender os incidentes. A primeira é o pacote falso, criado com nome parecido com um pacote legítimo. Esse golpe é chamado de typosquatting quando depende de erros de digitação, como instalar um nome quase igual ao correto.

A segunda é o pacote legítimo comprometido. Esse é o caso mais grave. O nome é real, o pacote já era confiável, a conta de publicação parecia legítima e a versão apareceu no registro oficial. O ataque ao Axios e as ondas envolvendo TanStack, Nx, chalk, debug e @antv entram nessa categoria ou em variações próximas dela.

A terceira é a dependência transitiva comprometida. Nesse cenário, o projeto não declara o pacote malicioso diretamente. Ele instala uma dependência legítima, e essa dependência puxa outra dependência que foi comprometida. Isso torna a detecção mais difícil, porque a origem do risco fica escondida em níveis profundos da árvore.

Essas categorias podem aparecer juntas. Um invasor pode comprometer um pacote legítimo e, ao mesmo tempo, adicionar uma dependência maliciosa externa. Foi uma característica importante no ataque ao Axios, em que versões comprometidas adicionaram uma dependência preparada para executar o payload.

Linha do tempo resumida dos principais incidentes

A linha do tempo ajuda a perceber que não foi um evento isolado. O npm passou por várias ondas, cada uma com técnicas e impacto diferentes. Algumas campanhas buscaram roubo de credenciais. Outras tentaram propagação automática. Outras exploraram pipelines modernos com OIDC e provenance.

  • Agosto de 2025 — Nx / s1ngularity: versões maliciosas de pacotes Nx foram publicadas após extração de token npm em um fluxo de GitHub Actions. O payload buscava dados sensíveis e enviava resultados para repositórios públicos.
  • Setembro de 2025 — chalk, debug e pacotes relacionados: pacotes muito usados receberam versões comprometidas. A campanha teve grande impacto potencial por atingir dependências com downloads massivos.
  • Setembro de 2025 — Shai-Hulud: pesquisadores descreveram um worm capaz de roubar credenciais e tentar publicar novas versões maliciosas em outros pacotes mantidos pela vítima.
  • Março de 2026 — Axios: versões maliciosas de Axios foram publicadas e adicionaram uma dependência maliciosa usada para entregar um RAT, sigla para ferramenta de acesso remoto.
  • Abril e maio de 2026 — Mini Shai-Hulud: novas ondas atingiram TanStack, Mistral AI, UiPath, Squawk, OpenSearch, PyPI e outros projetos.
  • Maio de 2026 — @antv e pacotes relacionados: uma conta de mantenedor ligada ao ecossistema @antv publicou centenas de versões maliciosas em curto intervalo.

O caso chalk, debug e pacotes relacionados

O caso envolvendo chalk, debug e outros pacotes demonstrou o risco de pacotes pequenos, mas extremamente centrais. Bibliotecas desse tipo aparecem em muitas árvores de dependências, muitas vezes de forma indireta. A Vercel, a Semgrep, a Aikido, a Sonatype e outras empresas publicaram análises sobre a campanha.

O impacto potencial foi grande porque vários desses pacotes são usados em ferramentas de build, CLIs e bibliotecas populares. Em uma cadeia de dependências do npm, uma alteração em pacote pequeno pode chegar a aplicações grandes. Isso mostra que popularidade não significa imunidade contra comprometimento.

Os pacotes principais citados nessa onda foram os seguintes.

  • ansi-styles@6.2.2
  • strip-ansi@7.1.1
  • ansi-regex@6.2.1
  • debug@4.4.2
  • color-convert@3.1.1
  • color-name@2.0.1
  • supports-color@10.2.1
  • chalk@5.6.1
  • wrap-ansi@9.0.1
  • slice-ansi@7.1.1
  • color@5.0.1
  • color-string@2.1.1
  • is-arrayish@0.3.3
  • simple-swizzle@0.2.3
  • supports-hyperlinks@4.1.1
  • has-ansi@6.0.1
  • chalk-template@1.1.1
  • backslash@0.2.1

O caso Nx e s1ngularity

O Nx é uma ferramenta usada para organizar monorepos, builds e aplicações modernas. No incidente conhecido como s1ngularity, os próprios mantenedores informaram que atacantes exploraram uma falha em GitHub Actions, extraíram um token de publicação npm e publicaram versões maliciosas por algumas horas.

O detalhe importante é que o pipeline oficial não precisava ter sido totalmente dominado para o ataque causar dano. O token roubado já permitia publicar versões no npm. A publicação ficava com aparência legítima para quem apenas olhava o pacote no registro.

Segundo o post-mortem do Nx, os pacotes maliciosos rodavam um script pós-instalação, procuravam dados sensíveis no sistema e tentavam usar ferramentas locais. Parte dos dados era enviada para repositórios públicos criados nas contas das vítimas. Esse comportamento deixou rastros, mas também exigiu resposta rápida de rotação de credenciais.

Os pacotes principais envolvidos no alerta Nx foram os seguintes.

  • nx
  • @nx/devkit
  • @nx/js
  • @nx/workspace
  • @nx/node
  • @nx/eslint
  • @nx/key
  • @nx/enterprise-cloud

O caso Shai-Hulud original

O Shai-Hulud foi descrito por pesquisadores como uma evolução importante porque trouxe comportamento de worm para o ecossistema npm. Um worm é um malware que tenta se espalhar automaticamente. Nesse caso, a ideia era roubar credenciais de publicação e usá-las para comprometer outros pacotes mantidos pela vítima.

A StepSecurity relatou que a campanha atingiu mais de 500 pacotes npm, incluindo @ctrl/tinycolor. O malware buscava credenciais em variáveis de ambiente, arquivos locais, serviços cloud e ferramentas de desenvolvimento. Ele também tentava criar persistência por meio de GitHub Actions.

O ponto didático mais importante é que o malware não precisava quebrar a criptografia de um serviço cloud. Ele procurava credenciais já disponíveis no ambiente. Em um CI/CD mal configurado, variáveis como tokens GitHub, chaves AWS e tokens npm podem estar presentes durante a instalação das dependências.

Alguns pacotes citados nas listas públicas da onda Shai-Hulud foram os seguintes.

  • @ahmedhfarag/ngx-perfect-scrollbar
  • @ahmedhfarag/ngx-virtual-scroller
  • @art-ws/common
  • @art-ws/config-eslint
  • @art-ws/config-ts
  • @art-ws/db-context
  • @art-ws/di
  • @art-ws/di-node
  • @art-ws/eslint
  • @art-ws/fastify-http-server
  • @art-ws/http-server
  • @art-ws/openapi
  • @art-ws/package-base
  • @art-ws/prettier
  • @art-ws/slf
  • @art-ws/ssl-info
  • @art-ws/web-app
  • @crowdstrike/commitlint
  • @crowdstrike/falcon-shoelace
  • @crowdstrike/foundry-js
  • @crowdstrike/glide-core
  • @crowdstrike/logscale-dashboard
  • @crowdstrike/logscale-file-editor
  • @crowdstrike/logscale-parser-edit
  • @crowdstrike/logscale-search
  • @crowdstrike/tailwind-toucan-base
  • @ctrl/deluge
  • @ctrl/golang-template
  • @ctrl/magnet-link
  • @ctrl/ngx-codemirror
  • @ctrl/ngx-csv
  • @ctrl/ngx-emoji-mart
  • @ctrl/ngx-rightclick
  • @ctrl/qbittorrent
  • @ctrl/react-adsense
  • @ctrl/shared-torrent
  • @ctrl/tinycolor
  • @ctrl/torrent-file
  • @ctrl/transmission
  • @ctrl/ts-base32
  • @hestjs/core
  • @hestjs/cqrs
  • @hestjs/demo
  • @hestjs/eslint-config
  • @hestjs/logger
  • @hestjs/scalar
  • @hestjs/validation
  • @nativescript-community/arraybuffers
  • @nativescript-community/gesturehandler
  • @nativescript-community/perms
  • @nativescript-community/sentry
  • encounter-playground
  • eslint-config-crowdstrike
  • eslint-config-crowdstrike-node
  • eslint-config-teselagen
  • globalize-rpk
  • graphql-sequelize-teselagen
  • html-to-base64-image
  • json-rules-engine-simplified
  • jumpgate
  • koa2-swagger-ui
  • mcfly-semantic-release
  • mcp-knowledge-base
  • mcp-knowledge-graph
  • yoo-styles

O caso Axios

O ataque ao Axios teve grande repercussão porque Axios é uma biblioteca HTTP usada em muitos projetos JavaScript, tanto no navegador quanto no Node.js. A Aikido, a Snyk, a Trend Micro, a Unit 42, a Sophos e outras fontes relataram que duas versões maliciosas foram publicadas no npm.

As versões citadas foram axios@1.14.1 e axios@0.30.4. Elas adicionaram uma dependência chamada plain-crypto-js@4.2.1, que foi usada como parte da cadeia maliciosa. O código malicioso era voltado para macOS, Windows e Linux, o que ampliava o risco para máquinas de desenvolvimento e ambientes automatizados.

Esse caso é um exemplo claro de ataque em pacote legítimo. O nome axios era real, o registro era o npm oficial e o pacote era famoso. O perigo não estava em instalar um nome errado, mas em uma versão ruim de um nome correto.

Os artefatos principais citados no caso Axios foram os seguintes.

  • axios@1.14.1
  • axios@0.30.4
  • plain-crypto-js@4.2.1

O caso TanStack e Mini Shai-Hulud

A onda envolvendo TanStack mostrou que controles modernos também podem ser contornados quando o próprio pipeline de build é sequestrado. A Snyk relatou que 84 artefatos maliciosos foram publicados em 42 pacotes do namespace @tanstack em poucos minutos. A campanha também se espalhou para Mistral AI, UiPath, Squawk, OpenSearch, Guardrails AI e outros projetos.

O detalhe mais importante é que algumas publicações carregavam sinais modernos de provenance. Provenance é uma prova criptográfica que tenta demonstrar a origem de um pacote. Ela é útil, mas não prova que o código construído era seguro. Se o pipeline legítimo constrói código alterado por um invasor, a assinatura pode atestar corretamente um processo que já foi comprometido.

A Aikido informou que a campanha detectada em maio de 2026 envolvia 373 entradas de versões maliciosas em 169 nomes de pacotes npm. A meta continuava sendo roubar credenciais de máquinas de desenvolvedores e runners de CI/CD, depois usar essas credenciais para alcançar mais pacotes.

Uma lista ampliada de pacotes e namespaces citados na onda Mini Shai-Hulud é apresentada abaixo. A lista junta pacotes TanStack, Mistral, UiPath, Squawk e outros citados em relatórios públicos.

  • @tanstack/history
  • @tanstack/react-router
  • @tanstack/router-core
  • @tanstack/router-utils
  • @tanstack/router-plugin
  • @tanstack/virtual-file-routes
  • @tanstack/router-generator
  • @tanstack/start-server-core
  • @tanstack/start-client-core
  • @tanstack/start-storage-context
  • @tanstack/start-plugin-core
  • @tanstack/react-start-server
  • @tanstack/react-start-client
  • @tanstack/start-fn-stubs
  • @tanstack/react-start
  • @tanstack/react-start-rsc
  • @tanstack/react-router-devtools
  • @tanstack/router-devtools-core
  • @tanstack/router-devtools
  • @tanstack/router-ssr-query-core
  • @tanstack/react-router-ssr-query
  • @tanstack/router-cli
  • @tanstack/zod-adapter
  • @tanstack/eslint-plugin-router
  • @tanstack/router-vite-plugin
  • @tanstack/nitro-v2-vite-plugin
  • @tanstack/solid-router
  • @tanstack/solid-start
  • @tanstack/solid-start-client
  • @tanstack/solid-start-server
  • @tanstack/solid-router-devtools
  • @tanstack/start-static-server-functions
  • @tanstack/vue-router
  • @tanstack/solid-router-ssr-query
  • @tanstack/valibot-adapter
  • @tanstack/vue-start
  • @tanstack/vue-start-server
  • @tanstack/vue-start-client
  • @tanstack/arktype-adapter
  • @tanstack/eslint-plugin-start
  • @tanstack/vue-router-ssr-query
  • @tanstack/vue-router-devtools
  • @mistralai/mistralai
  • @mistralai/mistralai-gcp
  • @mistralai/mistralai-azure
  • @uipath/apollo-react
  • @uipath/apollo-wind
  • @uipath/cli
  • @uipath/rpa-tool
  • @uipath/apollo-core
  • @uipath/filesystem
  • @uipath/solutionpackager-tool-core
  • @uipath/solution-tool
  • @uipath/maestro-tool
  • @uipath/codedapp-tool
  • @uipath/agent-tool
  • @uipath/orchestrator-tool
  • @uipath/integrationservice-tool
  • @uipath/rpa-legacy-tool
  • @uipath/vertical-solutions-tool
  • @uipath/flow-tool
  • @uipath/codedagent-tool
  • @uipath/common
  • @uipath/resource-tool
  • @uipath/auth
  • @uipath/docsai-tool
  • @uipath/case-tool
  • @uipath/api-workflow-tool
  • @uipath/test-manager-tool
  • @uipath/robot
  • @uipath/traces-tool
  • @uipath/agent-sdk
  • @uipath/integrationservice-sdk
  • @uipath/maestro-sdk
  • @uipath/data-fabric-tool
  • @uipath/tasks-tool
  • @uipath/insights-tool
  • @uipath/insights-sdk
  • @uipath/uipath-python-bridge
  • @uipath/ap-chat
  • @uipath/project-packager
  • @uipath/packager-tool-case
  • @uipath/packager-tool-workflowcompiler-browser
  • @uipath/packager-tool-connector
  • @uipath/packager-tool-workflowcompiler
  • @uipath/packager-tool-webapp
  • @uipath/packager-tool-apiworkflow
  • @uipath/packager-tool-functions
  • @uipath/resources-tool
  • @uipath/agent.sdk
  • @uipath/codedagents-tool
  • @uipath/aops-policy-tool
  • @uipath/solution-packager
  • @uipath/packager-tool-bpmn
  • @uipath/packager-tool-flow
  • @uipath/telemetry
  • @uipath/tool-workflowcompiler
  • @uipath/vss
  • @uipath/access-policy-tool
  • @uipath/context-grounding-tool
  • @uipath/gov-tool
  • @uipath/admin-tool
  • @uipath/identity-tool
  • @uipath/llmgw-tool
  • @uipath/resourcecatalog-tool
  • @uipath/functions-tool
  • @uipath/access-policy-sdk
  • @uipath/platform-tool
  • @squawk/types
  • @squawk/mcp
  • @squawk/weather
  • @squawk/airspace
  • @squawk/icao-registry-data
  • @squawk/flightplan
  • @squawk/airports
  • @squawk/geo
  • @squawk/procedure-data
  • @squawk/navaid-data
  • @squawk/fix-data
  • @squawk/navaids
  • @squawk/fixes
  • @squawk/airport-data
  • @squawk/airway-data
  • @squawk/units
  • @squawk/procedures
  • @squawk/airways
  • @squawk/icao-registry
  • @squawk/notams
  • @squawk/flight-math
  • @squawk/airspace-data
  • safe-action
  • @mesadev/sdk
  • @mesadev/rest
  • @mesadev/saguaro
  • @draftlab/auth
  • @draftlab/db
  • @draftlab/auth-router
  • @draftauth/core
  • @draftauth/client
  • @taskflow-corp/cli
  • ts-dna
  • cross-stitch
  • cmux-agent-mcp
  • agentwork-cli
  • @dirigible-ai/sdk
  • git-branch-selector
  • wot-api
  • git-git-git
  • @beproduct/nestjs-auth
  • @ml-toolkit-ts/xgboost
  • nextmove-mcp
  • ml-toolkit-ts
  • @ml-toolkit-ts/preprocessing
  • @tallyui/connector-medusa
  • @tallyui/connector-shopify
  • @tallyui/theme
  • @tolka/cli
  • @supersurkhet/cli
  • @supersurkhet/sdk

O caso @antv, echarts-for-react, size-sensor e timeago.js

O ecossistema @antv é usado em visualização de dados, gráficos e dashboards. Em maio de 2026, a Microsoft relatou uma campanha ativa que atingiu pacotes @antv e bibliotecas relacionadas, com foco em roubo de credenciais de ambientes CI/CD.

A SafeDep informou que uma conta npm comprometida publicou centenas de versões maliciosas em centenas de pacotes em um intervalo muito curto. Entre os pacotes de maior impacto citados estavam size-sensor, echarts-for-react, @antv/scale e timeago.js. A Microsoft também citou roubo de credenciais envolvendo GitHub, AWS, HashiCorp Vault, npm, Kubernetes e 1Password.

Essa onda mostra outro detalhe perigoso. Mesmo quando a tag latest não é alterada, projetos com range semântico podem resolver para uma versão mais alta comprometida. Portanto, confiar apenas na tag latest não é suficiente.

A lista abaixo reúne muitos dos pacotes citados na onda @antv e em pacotes relacionados. As versões específicas devem ser confirmadas nas fontes de referência, pois algumas listas foram atualizadas durante a resposta ao incidente.

  • ai-figure
  • amapcn
  • @antv/a8
  • @antv/adjust
  • @antv/algorithm
  • @antv/async-hook
  • @antv/attr
  • @antv/ava
  • @antv/ava-react
  • @antv/awards
  • @antv/calendar-heatmap
  • @antv/chart-linter
  • @antv/chart-node-g6
  • @antv/chart-visualization-skills
  • @antv/ckb
  • @antv/color-schema
  • @antv/color-util
  • @antv/component
  • @antv/coord
  • @antv/d3-color
  • @antv/d3-interpolate
  • @antv/data-samples
  • @antv/data-set
  • @antv/data-wizard
  • @antv/dipper-component
  • @antv/dipper-hooks
  • @antv/dipper-map
  • @antv/dom-util
  • @antv/dumi-theme-antv
  • @antv/dw-analyzer
  • @antv/dw-random
  • @antv/dw-transform
  • @antv/dw-util
  • @antv/event-emitter
  • @antv/expr
  • @antv/f2
  • @antv/f2-algorithm
  • @antv/f2-canvas
  • @antv/f2-context
  • @antv/f2-graphic
  • @antv/f2-my
  • @antv/f2-react
  • @antv/f2-site
  • @antv/f2-vue
  • @antv/f2-wordcloud
  • @antv/f2-wx
  • @antv/f6
  • @antv/f6-alipay
  • @antv/f6-core
  • @antv/f6-element
  • @antv/f6-hammerjs
  • @antv/f6-plugin
  • @antv/f6-ui
  • @antv/f6-wx
  • @antv/f-charts
  • @antv/f-engine
  • @antv/f-lottie
  • @antv/f-my
  • @antv/f-react
  • @antv/f-test-utils
  • @antv/f-vue
  • @antv/f-wx
  • @antv/g2
  • @antv/g2-brush
  • @antv/g2-extension-3d
  • @antv/g2-extension-ava
  • @antv/g2-extension-plot
  • @antv/g2plot
  • @antv/g2plot-schemas
  • @antv/g2-plugin-slider
  • @antv/g2-ssr
  • @antv/g
  • @antv/g6
  • @antv/g6-alipay
  • @antv/g6-cli
  • @antv/g6-core
  • @antv/g6-editor
  • @antv/g6-element
  • @antv/g6-extension-3d
  • @antv/g6-extension-react
  • @antv/g6-mobile
  • @antv/g6-pc
  • @antv/g6-plugin
  • @antv/g6-plugin-map-view
  • @antv/g6-plugins
  • @antv/g6-react-node
  • @antv/g6-ssr
  • @antv/g6-wx
  • @antv/gatsby-theme
  • @antv/g-base
  • @antv/g-camera-api
  • @antv/g-canvas
  • @antv/g-canvaskit
  • @antv/g-compat
  • @antv/g-components
  • @antv/g-css-layout-api
  • @antv/g-css-typed-om-api
  • @antv/g-device-api
  • @antv/g-dom-mutation-observer-api
  • @antv/geo-coord
  • @antv/g-gesture
  • @antv/gi-assets-advance
  • @antv/gi-assets-algorithm
  • @antv/gi-assets-basic
  • @antv/gi-assets-galaxybase
  • @antv/gi-assets-graphscope
  • @antv/gi-assets-hugegraph
  • @antv/gi-assets-janusgraph
  • @antv/gi-assets-neo4j
  • @antv/gi-assets-scene
  • @antv/gi-assets-tugraph
  • @antv/gi-assets-tugraph-analytics
  • @antv/gi-assets-xlab
  • @antv/gi-cli
  • @antv/gi-common-components
  • @antv/g-image-exporter
  • @antv/gi-mock-data
  • @antv/gi-public-data
  • @antv/gi-sdk
  • @antv/gi-sdk-app
  • @antv/gi-theme-antd
  • @antv/g-plugin-canvas-renderer
  • @antv/g-plugin-device-renderer
  • @antv/g-plugin-dom-interaction
  • @antv/g-plugin-dragndrop
  • @antv/g-plugin-webgl-renderer
  • @antv/gpt-vis
  • @antv/graphin
  • @antv/graphlib
  • @antv/l7
  • @antv/l7-core
  • @antv/l7-map
  • @antv/l7-maps
  • @antv/l7-scene
  • @antv/l7-source
  • @antv/larkmap
  • @antv/s2
  • @antv/scale
  • @antv/util
  • @antv/vendor
  • @antv/x6
  • size-sensor
  • echarts-for-react
  • timeago.js
  • jest-canvas-mock
  • jest-date-mock
  • canvas-nest.js

O que também aconteceu em PyPI

O PyPI é o principal repositório de pacotes Python. Ele também foi afetado por campanhas de cadeia de suprimentos, especialmente em pacotes usados por projetos de inteligência artificial e automação. A campanha Mini Shai-Hulud cruzou fronteiras entre ecossistemas e atingiu pacotes npm e PyPI.

O caso do pacote mistralai==2.4.6 no PyPI foi citado por fontes como LiteLLM e alertas públicos. Também houve referência a guardrails-ai==0.10.1. Em outros incidentes, versões de litellm foram relatadas como comprometidas por veículos especializados e removidas após descoberta.

O detalhe técnico importante no PyPI é que nem todo ataque depende de scripts de instalação. Em Python, uma biblioteca pode executar código quando importada. Portanto, um pacote malicioso pode não agir no momento do install, mas sim quando o programa executa import nome_do_pacote.

Pacotes PyPI citados em alertas e matérias públicas incluem os seguintes.

  • mistralai==2.4.6
  • guardrails-ai==0.10.1
  • litellm==1.82.7
  • litellm==1.82.8

O que também aconteceu em NuGet

O NuGet é o repositório de pacotes usado no ecossistema .NET. Ele aparece em escala menor do que npm e PyPI nas campanhas analisadas, mas também teve casos importantes. A ReversingLabs relatou pacotes maliciosos mirando desenvolvedores de criptomoedas, OAuth e, mais recentemente, um pacote falso relacionado ao Stripe.

O caso StripeApi.Net é didático porque mostra um pacote falso que imitava a biblioteca legítima Stripe.net. Esse tipo de ataque tenta explorar a confiança do desenvolvedor em nomes familiares. A vítima instala o pacote errado, e o código malicioso tenta capturar tokens de API ou credenciais úteis.

No NuGet, também foram relatadas campanhas que imitavam ferramentas ligadas a Nethereum, Coinbase, Binance e Solana. Esses casos reforçam que o problema não pertence a uma linguagem específica. Qualquer ecossistema com registro público de pacotes e instalação automatizada pode ser usado como vetor.

Exemplos citados em fontes públicas sobre NuGet incluem os seguintes.

  • StripeApi.Net
  • pacotes falsos ligados a Nethereum
  • pacotes falsos ligados a Coinbase
  • pacotes falsos ligados a Binance
  • pacotes falsos ligados a Solana

O que os ataques tentam roubar

A maioria dos incidentes tinha uma lógica de roubo de credenciais. O malware não precisava quebrar sistemas complexos. Ele procurava segredos que já estavam presentes na máquina ou no pipeline. Isso é muito comum em ambientes de desenvolvimento, porque ferramentas precisam de credenciais para publicar pacotes, baixar dependências privadas e fazer deploy.

Os dados mais visados podem ser agrupados da seguinte forma.

  • Tokens npm: permitem publicar novas versões de pacotes, alterar permissões ou automatizar releases.
  • Tokens GitHub: permitem acessar repositórios, criar commits, ler código privado, abrir workflows e interagir com APIs.
  • Secrets de GitHub Actions: são variáveis protegidas usadas por workflows para deploy, testes, publicação e integração com serviços externos.
  • Chaves AWS, GCP e Azure: podem permitir leitura de buckets, secrets managers, filas, bancos, máquinas e outros recursos cloud.
  • Chaves SSH: podem permitir acesso a servidores, repositórios privados ou sistemas internos.
  • Arquivos .env: costumam guardar senhas de banco, tokens de API, chaves JWT, credenciais de email e endpoints internos.
  • Tokens de 1Password, Vault e gerenciadores de segredo: podem abrir caminho para credenciais ainda mais sensíveis.
  • Dados de carteiras cripto: foram alvos em algumas campanhas, especialmente quando o malware buscava chaves, extensões ou arquivos locais.

Como o roubo acontece em linguagem simples

O roubo normalmente começa quando um script do pacote é executado. Esse script pode ser um postinstall, um preinstall, um prepare ou uma etapa acionada por uma dependência Git. Em alguns casos, o malware só roda quando a biblioteca é importada.

Depois da execução, o código verifica o ambiente. Ele tenta descobrir se está em Linux, macOS, Windows, GitHub Actions, máquina local ou runner de CI. Em seguida, procura variáveis de ambiente, arquivos de configuração, diretórios conhecidos e tokens usados por CLIs.

Quando encontra credenciais, o malware tenta enviar os dados para fora. Essa saída de dados é chamada de exfiltração. Pode acontecer por API, webhook, repositório temporário, requisição HTTP, serviço de mensagens ou outro canal externo.

Algumas campanhas ainda tentam se espalhar. Se o malware encontra um token npm com permissão de publicação, ele pode tentar publicar novas versões maliciosas em outros pacotes. Se encontra token GitHub com permissões amplas, pode tentar alterar repositórios, criar workflows ou gravar dados em locais públicos.

Por que ignore-scripts ajuda, mas não resolve tudo

O parâmetro --ignore-scripts impede que scripts de ciclo de vida sejam executados automaticamente durante comandos como npm install ou npm ci. Isso reduz muito o risco de ataques baseados em preinstall, install, postinstall e prepare.

A proteção é importante porque muitos ataques de npm dependem exatamente da execução automática durante a instalação. No entanto, ela não resolve todos os cenários. Um pacote ainda pode conter código malicioso que só roda quando a aplicação importa ou executa a biblioteca.

Outro limite é que alguns pacotes legítimos usam scripts de instalação para compilar módulos nativos ou baixar binários. Desativar scripts pode quebrar builds que dependem desse comportamento. Por isso, a estratégia ideal é bloquear por padrão e liberar somente pacotes realmente necessários em ambientes controlados.

O comando abaixo define uma política global no npm para não executar scripts de instalação automaticamente.

# desativa scripts automáticos por padrão no npm
npm config set ignore-scripts true

# instalação limpa sem scripts em CI/CD
npm ci --ignore-scripts

# instalação comum sem scripts
npm install --ignore-scripts

Por que Bun aparece como alternativa mais segura nesse ponto

O Bun adota uma postura mais restritiva para scripts de ciclo de vida. A documentação oficial informa que o Bun não executa scripts arbitrários como postinstall para dependências instaladas, a menos que o pacote seja listado como confiável em trustedDependencies.

Esse comportamento ajuda contra uma classe comum de ataques do npm. Um pacote malicioso que depende de execução automática no install pode não rodar no Bun, a menos que tenha sido marcado como confiável. Isso não torna o Bun uma blindagem total, mas melhora o padrão de segurança inicial.

Quando um pacote realmente precisa rodar scripts de instalação, a liberação pode ser feita de forma explícita. Essa abordagem é melhor do que permitir tudo por padrão, porque transforma a execução de scripts em uma decisão consciente.

Um exemplo de configuração com trustedDependencies é apresentado abaixo.

{
  "name": "meu-projeto",
  "version": "1.0.0",
  "trustedDependencies": [
    "sharp",
    "esbuild"
  ]
}

Também é possível confiar em um pacote específico pelo comando do Bun.

# libera scripts apenas para um pacote específico
bun pm trust sharp

# instala dependências com o modelo de confiança do Bun
bun install

Plano de proteção passo a passo para projetos que consomem pacotes

A defesa mais eficaz é em camadas. Uma única ferramenta não bloqueia todos os cenários, porque os ataques podem acontecer em momentos diferentes. A proteção precisa cobrir instalação, lockfile, CI/CD, secrets, rede, revisão de dependências e resposta a incidentes.

O processo recomendado para projetos que usam npm é apresentado a seguir.

  1. Usar lockfile sempre: manter package-lock.json, pnpm-lock.yaml, yarn.lock ou bun.lock versionado no repositório.
  2. Preferir npm ci em CI/CD: o comando npm ci instala a árvore definida no lockfile, reduzindo mudanças inesperadas durante builds automatizados.
  3. Rodar install sem scripts por padrão: usar npm ci --ignore-scripts no CI, liberando exceções apenas quando houver necessidade comprovada.
  4. Evitar secrets durante install: credenciais de deploy, cloud e publicação não devem estar disponíveis na etapa que instala dependências.
  5. Fixar versões críticas: dependências sensíveis podem ser fixadas sem range amplo, reduzindo atualizações automáticas inesperadas.
  6. Revisar lockfile em pull requests: mudanças no lockfile devem ser tratadas como mudança de código, não como ruído.
  7. Aplicar atraso para versões novas: evitar instalar versões publicadas há poucos minutos ou poucas horas reduz exposição a ataques recém-publicados.
  8. Isolar builds: usar containers descartáveis, runners efêmeros e máquinas sem credenciais pessoais.
  9. Controlar saída de rede: bloquear conexões externas desnecessárias durante install e build dificulta exfiltração.
  10. Monitorar scripts de pacotes: identificar dependências que passaram a declarar preinstall, postinstall ou prepare.
  11. Rotacionar credenciais após suspeita: qualquer ambiente que instalou versão comprometida deve ser tratado como exposto.
  12. Usar ferramentas de análise: combinar npm audit, SCA, scanners de malware, secret scanning e monitoramento de CI/CD.

Modelo seguro de pipeline CI/CD

Um erro comum é liberar todos os secrets logo no começo do pipeline. Isso torna a etapa de instalação de dependências perigosa. Se um pacote malicioso roda durante o install, ele encontra credenciais que só seriam necessárias muito depois.

O modelo mais seguro separa etapas. A instalação de dependências roda primeiro, sem secrets sensíveis. Testes e build também podem rodar com permissões mínimas. Só depois, em etapa separada e protegida, entram credenciais de deploy, publicação ou acesso cloud.

Um desenho simples de pipeline seguro pode seguir esta ordem.

  • Clonar código com permissões mínimas.
  • Instalar dependências com lockfile e sem scripts automáticos.
  • Executar testes sem credenciais sensíveis.
  • Gerar build em ambiente isolado.
  • Injetar secrets somente na etapa final de deploy ou publicação.
  • Revogar ou expirar credenciais temporárias após o uso.

Um exemplo simplificado de workflow com separação de permissões é apresentado abaixo.

name: build-seguro

on:
  push:
    branches:
      - main

jobs:
  testar:
    runs-on: ubuntu-latest
    permissions:
      contents: read

    steps:
      - name: baixar codigo
        uses: actions/checkout@v4

      - name: configurar node
        uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: npm

      - name: instalar dependencias sem scripts
        run: npm ci --ignore-scripts

      - name: rodar testes
        run: npm test

  publicar:
    needs: testar
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write

    steps:
      - name: baixar codigo
        uses: actions/checkout@v4

      - name: configurar node
        uses: actions/setup-node@v4
        with:
          node-version: 22
          registry-url: https://registry.npmjs.org

      - name: instalar dependencias sem scripts
        run: npm ci --ignore-scripts

      - name: publicar com trusted publishing
        run: npm publish --provenance

Como revisar o lockfile

O lockfile registra a árvore exata de dependências instalada. Ele mostra versões, integridade e, em alguns gerenciadores, origem do pacote. Em ataques de supply chain, o lockfile pode revelar entrada de uma versão maliciosa ou de uma dependência nova inesperada.

A revisão deve procurar alterações suspeitas. Uma dependência que nunca existiu no projeto e apareceu sem explicação merece investigação. Uma mudança de pacote estável para versão publicada recentemente também merece cuidado. Dependências vindas de URL, GitHub ou tarball externo devem receber atenção extra.

Os pontos abaixo ajudam a revisar mudanças de lockfile.

  • Pacote novo que não aparece no package.json.
  • Versão nova publicada no mesmo dia do pull request.
  • Dependência com nome parecido com pacote famoso.
  • Mudança de origem do pacote para URL, GitHub ou tarball.
  • Pacote que passou a ter scripts de instalação.
  • Dependência transitiva que puxa pacote desconhecido.
  • Versões removidas, republicadas ou sem histórico claro.

Comandos úteis para inspeção de árvore de dependências são apresentados abaixo.

# mostra por que um pacote está instalado
npm explain nome-do-pacote

# lista a árvore de um pacote específico
npm ls nome-do-pacote

# lista toda a árvore de dependências
npm ls --all

# mostra metadados públicos de um pacote
npm view nome-do-pacote

# mostra scripts declarados no pacote
npm view nome-do-pacote scripts

Como verificar exposição a pacotes citados

A checagem deve começar pelo lockfile e pela árvore instalada. O lockfile mostra o que foi resolvido. O diretório node_modules mostra o que está instalado localmente, mas pode não ser suficiente quando o malware apaga rastros ou quando a instalação aconteceu em um runner descartável.

Os comandos abaixo procuram alguns pacotes citados nos incidentes. Eles não substituem scanners especializados, mas ajudam a localizar exposição inicial.

# pacotes da onda chalk/debug
npm ls chalk debug ansi-styles strip-ansi ansi-regex supports-color wrap-ansi color-convert color-name color color-string is-arrayish simple-swizzle supports-hyperlinks has-ansi chalk-template backslash

# pacotes do caso axios
npm ls axios plain-crypto-js

# pacotes do caso nx
npm ls nx @nx/devkit @nx/js @nx/workspace @nx/node @nx/eslint @nx/key @nx/enterprise-cloud

# pacotes de exemplo do shai-hulud
npm ls @ctrl/tinycolor @ctrl/deluge @ctrl/qbittorrent @crowdstrike/foundry-js @crowdstrike/glide-core

# pacotes de exemplo do mini shai-hulud
npm ls @tanstack/react-router @tanstack/vue-router @mistralai/mistralai @uipath/robot @squawk/mcp

# pacotes de exemplo do ecossistema antv
npm ls @antv/g2 @antv/g6 @antv/x6 @antv/scale echarts-for-react size-sensor timeago.js

Como responder se uma versão comprometida foi instalada

A resposta precisa considerar o ambiente como potencialmente comprometido. A simples remoção do pacote não basta. Se o malware já rodou, ele pode ter copiado credenciais, criado workflows, publicado versões, aberto conexões externas ou deixado persistência.

O processo recomendado de resposta é o seguinte.

  1. Isolar a máquina ou runner: interromper builds e evitar que o ambiente continue acessando rede interna ou serviços cloud.
  2. Preservar logs: guardar logs de CI/CD, histórico de instalação, lockfiles e registros de rede para investigação.
  3. Remover credenciais do ambiente: revogar tokens expostos antes de religar pipelines.
  4. Rotacionar secrets: trocar npm tokens, GitHub PATs, chaves cloud, chaves SSH, secrets de CI/CD, tokens de Vault e senhas de banco.
  5. Auditar repositórios: procurar branches, workflows, commits, webhooks e deploy keys criados sem autorização.
  6. Auditar pacotes publicados: mantenedores devem verificar se versões foram publicadas fora do processo normal.
  7. Recriar runners: ambientes afetados devem ser reconstruídos de imagem limpa, não apenas limpos manualmente.
  8. Reinstalar dependências de forma segura: usar lockfile conhecido, versões seguras e instalação sem scripts.
  9. Monitorar uso indevido: observar logs de cloud, GitHub, npm, deploy, banco e APIs por acessos incomuns.

Cuidados específicos para mantenedores de pacotes npm

Mantenedores possuem risco maior porque uma credencial roubada pode contaminar muitos usuários. Um token de publicação comprometido permite empurrar versões maliciosas para o registro. Por isso, a proteção precisa ser mais rígida do que em projetos que apenas consomem pacotes.

A primeira medida é reduzir tokens permanentes. O Trusted Publishing do npm permite publicar a partir de CI/CD usando OIDC, eliminando tokens npm de longa duração em muitos cenários. Isso não resolve todo tipo de ataque, mas reduz o risco de vazamento de token reutilizável.

A segunda medida é reforçar a conta. Contas de mantenedor devem usar 2FA forte, de preferência passkeys ou chaves de segurança compatíveis com FIDO2/WebAuthn. Senhas precisam ser únicas e guardadas em gerenciador confiável.

A terceira medida é revisar o processo de release. Publicações devem vir de pipeline conhecido, com revisão, provenance, permissões mínimas e alertas quando uma versão é publicada fora do fluxo normal. Em incidentes como Nx e Axios, a diferença entre publicação via pipeline e publicação manual foi um sinal importante.

Um conjunto de práticas para mantenedores é apresentado abaixo.

  • Preferir Trusted Publishing com OIDC.
  • Remover tokens npm clássicos sempre que possível.
  • Usar tokens granulares e de curta duração quando tokens forem inevitáveis.
  • Exigir 2FA para publicação e alteração de configurações.
  • Separar conta pessoal de conta usada em publicação.
  • Monitorar publicações fora do pipeline oficial.
  • Ativar provenance e verificar se a versão publicada tem origem esperada.
  • Proteger branches e tags de release.
  • Evitar release automático a partir de pull requests sem isolamento.
  • Revisar permissões de GitHub Actions e reduzir GITHUB_TOKEN.

Cuidados específicos para empresas e times

Empresas precisam tratar dependências como risco operacional. A escolha de uma biblioteca não é apenas decisão técnica. Ela afeta segurança, compliance, continuidade do negócio e integridade de deploys.

O ideal é existir uma política clara de dependências. Essa política deve dizer como novas bibliotecas entram no projeto, como atualizações são aprovadas, quais ferramentas verificam risco, quanto tempo esperar antes de instalar versão recém-publicada e quem responde a alertas de supply chain.

Também é importante centralizar logs. Ataques de supply chain muitas vezes deixam pistas em logs de CI/CD, DNS, firewall, proxy, GitHub, cloud e npm. Sem logs, a investigação vira tentativa de adivinhação.

Medidas úteis para times e empresas incluem as seguintes.

  • Catálogo interno de dependências aprovadas.
  • Política de atualização com atraso mínimo para versões recém-publicadas.
  • Ambientes de build sem secrets durante instalação.
  • Runners efêmeros e sem estado permanente.
  • Bloqueio de saída de rede por padrão no CI.
  • Secret scanning em repositórios e pipelines.
  • SCA, sigla para análise de composição de software.
  • SBOM, sigla para lista de componentes de software usados no projeto.
  • Alertas para publicações anormais em pacotes próprios.
  • Plano de resposta com rotação rápida de credenciais.

O papel do npm audit e de scanners

O npm audit é útil para vulnerabilidades conhecidas, mas não deve ser visto como proteção suficiente contra malware recém-publicado. Um pacote malicioso novo pode ainda não estar em uma base de advisories. Isso significa que um projeto pode passar no audit e ainda assim instalar algo perigoso.

Scanners de malware e ferramentas de análise de dependências ajudam a reduzir risco. Algumas ferramentas observam comportamento, metadados, scripts de instalação, idade da versão, reputação do mantenedor, mudança de ownership, presença de código ofuscado e comunicação externa suspeita.

A melhor abordagem é combinar ferramentas. O audit encontra vulnerabilidades conhecidas. O secret scanning encontra segredos vazados. O monitoramento de CI detecta conexões estranhas. A análise de pacotes encontra comportamento suspeito antes da instalação. Nenhum controle resolve tudo sozinho.

Exemplos de ferramentas e categorias úteis são apresentados abaixo.

  • npm audit: consulta vulnerabilidades conhecidas no ecossistema npm.
  • Dependabot: ajuda a abrir atualizações controladas e visíveis.
  • OSV Scanner: verifica dependências contra a base OSV.
  • Socket, Snyk, Aikido, SafeDep e similares: analisam risco de dependências e malware.
  • TruffleHog e GitHub Secret Scanning: ajudam a encontrar segredos expostos.
  • StepSecurity Harden-Runner: monitora comportamento e rede em GitHub Actions.
  • Semgrep: identifica padrões perigosos em código e configuração.

Configuração prática recomendada para npm

Uma configuração simples já reduz bastante o risco. Ela não substitui arquitetura segura, mas cria uma base melhor para projetos comuns. O objetivo é evitar instalação improvisada, reduzir execução automática e tornar atualizações mais previsíveis.

Os comandos abaixo representam uma base inicial de endurecimento para ambiente npm.

# usar npm ci no CI/CD, não npm install
npm ci --ignore-scripts

# configurar npm para ignorar scripts por padrão
npm config set ignore-scripts true

# verificar vulnerabilidades conhecidas
npm audit

# explicar por que um pacote está presente
npm explain nome-do-pacote

# visualizar scripts declarados por um pacote
npm view nome-do-pacote scripts

# visualizar metadados gerais
npm view nome-do-pacote

O arquivo package.json também pode usar versões fixas em dependências críticas. Isso reduz atualizações inesperadas. A desvantagem é que exige rotina de atualização ativa, para não deixar o projeto preso em versões antigas vulneráveis.

{
  "dependencies": {
    "axios": "1.14.0",
    "chalk": "5.6.0"
  },
  "overrides": {
    "axios": "1.14.0"
  }
}

O que evitar em projetos npm

Alguns hábitos aumentam muito o risco de supply chain. Muitos deles são convenientes no curto prazo, mas perigosos em ambientes reais. A proteção começa removendo atalhos inseguros.

Práticas que devem ser evitadas incluem as seguintes.

  • Rodar npm install em CI sem lockfile.
  • Permitir scripts de instalação de qualquer pacote sem revisão.
  • Usar secrets de produção durante a etapa de install.
  • Dar permissão ampla demais ao GITHUB_TOKEN.
  • Usar tokens npm permanentes e com escopo amplo.
  • Instalar dependências recém-publicadas sem atraso mínimo.
  • Ignorar mudanças grandes no lockfile.
  • Executar installs em máquina pessoal com chaves SSH, tokens cloud e carteiras locais.
  • Usar dependências por URL externa ou Git sem motivo claro.
  • Confiar apenas em popularidade ou número de downloads.

Como explicar o problema para iniciantes

Uma comparação simples ajuda. Um pacote npm é como uma peça de reposição usada dentro de uma máquina. Quando a peça vem de um fornecedor confiável, todos usam sem pensar muito. Mas se alguém invade o fornecedor e troca a peça por uma versão adulterada, a máquina final passa a carregar o problema sem saber.

No npm, a peça é o pacote. O fornecedor é o registro e a conta de mantenedor. A máquina é o projeto. O mecânico é o pipeline de build. Se a peça adulterada roda um script durante a instalação, ela pode olhar dentro da oficina e copiar chaves, documentos e senhas.

Por isso, a solução não é abandonar todas as dependências. O caminho realista é reduzir confiança automática. Pacotes precisam ser verificados, scripts precisam ser controlados, credenciais precisam ficar fora da etapa de instalação e ambientes precisam ser descartáveis.

A frase central para ensinar o tema é simples: dependência também é código. Se uma dependência roda durante o install ou durante o build, ela precisa ser tratada como qualquer outro código executável dentro do projeto.

Modelo de post de alerta com muitos emojis

O texto abaixo resume o tema em formato de post para rede social, com linguagem direta e chamativa.

🚨 ALERTA GRAVE PARA QUEM USA npm 🚨

O problema não é só pacote falso com nome parecido. O problema é muito pior: pacotes reais, famosos e usados por milhões de projetos receberam versões maliciosas. ⚠️

Foram citados em diferentes ondas pacotes e ecossistemas como axios, chalk, debug, ansi-styles, strip-ansi, nx, @nx/devkit, @ctrl/tinycolor, @tanstack/react-router, @tanstack/vue-router, @mistralai/mistralai, @uipath/robot, @squawk/mcp, @antv/g2, @antv/g6, @antv/x6, echarts-for-react, size-sensor e timeago.js. 🧨

O que o malware tenta roubar? 🔑 tokens npm, 🐙 tokens GitHub, ☁️ chaves AWS/GCP/Azure, 🧪 secrets de CI/CD, 🪪 chaves SSH, 📁 arquivos .env, 🔐 tokens de Vault/1Password e até 💰 dados de carteiras cripto em algumas campanhas.

A defesa começa com uma ideia simples: instalação de dependência é execução de código. Use lockfile. Use npm ci. Rode install sem scripts. Não exponha secrets durante npm install. Revise o lockfile. Use runners descartáveis. Controle saída de rede. Rotacione credenciais se houver suspeita. 🛡️

Bun ajuda nesse ponto porque não executa scripts arbitrários de dependências por padrão e usa trustedDependencies para liberar exceções. ✅

Dependência também é código. Código de terceiro também pode executar. Um pacote comprometido pode abrir a porta do projeto inteiro. 🚨

Checklist rápido de proteção

O checklist abaixo resume as ações mais importantes em linguagem prática.

  • Lockfile versionado e revisado.
  • npm ci em CI/CD.
  • npm ci --ignore-scripts como padrão de build.
  • Segredos removidos da etapa de instalação.
  • Runners efêmeros e containers descartáveis.
  • Permissões mínimas para GITHUB_TOKEN.
  • Trusted Publishing com OIDC para pacotes próprios.
  • 2FA forte em npm e GitHub.
  • Tokens granulares e de curta duração.
  • Revisão de scripts preinstall, install, postinstall e prepare.
  • Monitoramento de rede no CI/CD.
  • Secret scanning ativo.
  • Rotação de credenciais após qualquer instalação suspeita.
  • Política de atraso para versões recém-publicadas.
  • Auditoria de pacotes publicados fora do pipeline oficial.

Conclusão

Os incidentes recentes mostram que o npm se tornou uma das superfícies mais sensíveis da cadeia de suprimentos de software. O problema não é apenas a existência de pacotes maliciosos. O risco maior aparece quando pacotes legítimos, muito usados e aparentemente confiáveis recebem versões comprometidas.

PyPI e NuGet também fazem parte do mesmo cenário. O PyPI foi atingido por campanhas ligadas a pacotes de inteligência artificial e automação. O NuGet teve casos relevantes de pacotes falsos que imitavam bibliotecas legítimas para roubar tokens e credenciais. O padrão geral é o mesmo: atacar o ponto de confiança do desenvolvedor.

A solução não é parar de usar bibliotecas open source. A solução é tratar dependências como código executável, reduzir confiança automática, controlar scripts, proteger secrets, isolar builds, revisar lockfiles, usar OIDC quando possível e responder rapidamente quando uma versão comprometida aparece.

O princípio final é direto: um pacote popular pode ser seguro hoje e perigoso amanhã. Segurança de dependências não é uma verificação única. É um processo contínuo de atualização, validação, isolamento e resposta.

Referências externas

As fontes abaixo foram usadas para consolidar a pesquisa, explicar os incidentes e organizar as práticas de proteção. Elas incluem advisories oficiais, post-mortems, documentação de ferramentas e análises de empresas de segurança.