Nos últimos anos vimos uma escalada preocupante de ataques à cadeia de suprimentos em ecossistemas de pacotes, e o npm virou um alvo recorrente. Seu projeto não precisa usar nenhuma “lib obscura” para estar em risco: basta depender de um pacote popular o suficiente para atrair a atenção dos atacantes.
Depois do caso CanisterWorm — em que o comprometimento do Trivy resultou na infecção de dezenas de pacotes npm — surgiu outro alerta vermelho: o incidente envolvendo o axios, uma das bibliotecas HTTP mais usadas em projetos JavaScript/TypeScript no frontend (React, Next.js) e no backend (Node.js, NestJS, Express, etc.).
Este artigo complementa o texto anterior sobre o CanisterWorm e aprofunda um caso específico: quando um pacote mainstream como o axios se torna o “Cavalo de Troia” dentro do seu pipeline.
De vulnerabilidade “normal” a comprometimento de conta
É importante separar duas coisas:
- Vulnerabilidades de segurança no código do axios
São falhas como SSRF, prototype pollution ou bugs em validação de URLs. Elas são descobertas, recebem CVE, são corrigidas em releases subsequentes e entram nos relatórios de ferramentas comonpm auditou Snyk. - Comprometimento de cadeia de suprimentos (supply chain)
Aqui não estamos falando de “um bug na biblioteca”, e sim de uma conta de maintainer comprometida ou de uma cadeia de publicação invadida. O resultado é um pacote “oficial”, com o mesmo nome, sendo publicado com código malicioso deliberado, geralmente para:- instalar um backdoor no ambiente;
- exfiltrar credenciais;
- plantar um RAT (Remote Access Trojan);
- quebrar a integridade do build.
No caso do axios, o que chamou atenção não foi apenas uma CVE, mas sim o fato de versões específicas terem sido publicadas com payload malicioso. Ou seja: seu npm install ou pnpm install virou o primeiro estágio do ataque.
O que aconteceu com o axios
O cenário típico de um incidente de supply chain com um pacote popular costuma seguir alguns passos:
- Um atacante compromete a conta de um maintainer (phishing, vazamento de token, falha na proteção 2FA etc.).
- Usando esse acesso, ele publica uma ou mais versões novas do pacote, com:
- código adicional “ofuscado”;
- dependências suspeitas que não existiam antes;
- scripts de instalação (
postinstall) que baixam e executam binários ou payloads remotos.
- Como é uma versão “oficial”, hospedada no mesmo namespace, quem usa ranges soltos (
^,~,*) ou instala “a versão mais recente” acaba puxando essa release maliciosa automaticamente. - A partir daí, o atacante ganha presença no ambiente de desenvolvimento e/ou CI/CD.
No caso do axios, tivemos versões específicas marcadas posteriormente como maliciosas, que passaram a instalar um RAT durante o fluxo de instalação. O ataque não dependia de você usar alguma API exótica do axios no código: bastava rodar o comando de instalação para a porta dos fundos ser aberta.
Isso é o ponto-chave:
não é uma vulnerabilidade explorada em tempo de execução pela sua aplicação; é o momento de build/instalação que vira o vetor de comprometimento.
Por que o incidente com o axios é tão grave
Quando um pacote mainstream é comprometido, os impactos se multiplicam:
- Alcance massivo
axios é usado em milhões de projetos, bibliotecas e CLIs. Ele faz parte da “infraestrutura” de muitos stacks, assim comolodash,typescript,webpack, etc. - Confiança implícita
Por ser famoso e amplamente adotado, muitos times nunca pararam para auditar minimamente as versões usadas. O pacote entra uma vez nopackage.jsone depois fica anos sendo atualizado no automático. - Efeito dominó
Se uma ferramenta de build, um SDK ou uma lib interna dependem de axios, qualquer projeto que use essas camadas também passa a estar exposto. Isso transforma um único comprometimento em um incidente transversal. - Superfície CI/CD
O payload malicioso frequentemente instala um RAT ou algum agente de comando e controle na máquina de desenvolvimento ou no runner de CI:- acesso a tokens de repositório;
- credenciais de nuvem;
- chaves SSH;
- segredos do pipeline (bancos, mensagerias, serviços third-party).
No caso do axios, o episódio reforça uma mensagem incômoda: você não consegue mais confiar cegamente em “pacotes conhecidos”. A discussão deixa de ser “essa lib é famosa, então é segura” para “como eu enxergo e controlo o que entra na minha supply chain”.
O elo fraco: versionamento solto e scripts de instalação
Dois padrões comuns em projetos amplificam o impacto desse tipo de ataque:
1. Versões flutuantes (o famoso ^ e ~)
A prática “padrão” do ecossistema npm é instalar pacotes com version ranges:
"axios": "^1.7.0""axios": "~1.7.2"- ou até
"axios": "*"
Isso significa que:
- na sua máquina hoje, pode ter instalado
1.7.3; - no CI amanhã, pode vir
1.7.4; - e se um atacante publicar
1.7.5malicioso, essa pode ser a versão usada em produção sem nenhuma revisão.
Quando o pacote comprometido é central como o axios, range + falta de pinning + lockfile negligenciado = receita para desastre.
2. Scripts de ciclo de vida (postinstall, prepare, etc.)
O npm (e ferramentas compatíveis) executa scripts definidos no package.json dos pacotes:
preinstallinstallpostinstallprepare
Esses scripts podem:
- baixar arquivos da internet;
- compilar binários;
- rodar comandos shell arbitrários.
Para muita coisa legítima isso é necessário (ex.: pacotes que compilam addons nativos). Mas, em um incidente de supply chain, é exatamente aí que o atacante injeta o payload.
No caso do axios, o comportamento malicioso veio justamente via instalação, com dependências ou scripts extras que não faziam parte do histórico normal do pacote.
Como saber se meu projeto foi impactado
Se você mantém projetos que usam axios (direta ou indiretamente), algumas ações são essenciais:
- Audite as versões
- Rode
npm ls axios,pnpm list axiosouyarn why axios. - Verifique:
- qual versão está efetivamente instalada;
- se seu range (
^/~) permitiria resolver para versões marcadas como maliciosas.
- Rode
- Revise lockfiles
- Abra
package-lock.json,pnpm-lock.yamlouyarn.locke procure poraxios@<versão>que caia na janela de comprometimento. - Se um lockfile fixou uma versão maliciosa, você precisa:
- alterar o
package.jsonpara uma versão segura; - remover o lockfile e regenerá-lo;
- reinstalar dependências em um ambiente limpo.
- alterar o
- Abra
- Analise histórico de builds
- Verifique quando as dependências foram atualizadas pela última vez.
- Se houve builds em janelas de tempo alinhadas com o incidente e você usava ranges permissivos, trate o ambiente como potencialmente comprometido:
- girar credenciais;
- revisar access tokens;
- auditar ações executadas no CI/CD.
- Verifique pacotes intermediários
- Mesmo que você não use axios diretamente, alguma lib pode trazê-lo como dependência:
- SDKs de APIs;
- bibliotecas de autenticação;
- clientes HTTP genéricos.
- Mesmo que você não use axios diretamente, alguma lib pode trazê-lo como dependência:
Boas práticas para endurecer sua cadeia de suprimentos
O incidente com o axios não é o primeiro e não será o último. O que muda é o seu modelo de defesa. Algumas práticas concretas:
1. Adotar version pinning estratégico
- Para pacotes críticos (como axios, libs HTTP, ferramentas de build, autenticação, criptografia), evite
^e~. Prefira:"axios": "1.8.3"em vez de"^1.8.3".
- Use ranges controlados apenas onde faz sentido e com automação por cima (Renovate, Dependabot):
- atualizações pequenas automáticas + testes;
- PRs explícitas para upgrades maiores.
2. Tratar lockfile como artefato de segurança
- Sempre commit o lockfile.
- Em CI/CD, use:
npm ciem vez denpm install;- e, quando possível,
npm ci --ignore-scripts(ativando scripts apenas onde estritamente necessário).
- Em pipelines mais sensíveis, considere:
- build em ambiente isolado;
- verificação de integridade de pacotes (checksum, assinatura, proveniência).
3. Desconfiar de scripts de instalação
- Tenha uma política para libs que executam
postinstallouprepare. - Prefira soluções que não dependam de scripts automáticos quando for viável.
- Para pacotes internos:
- evite usar
postinstallpara coisas que podem ser resolvidas via comandos explícitos de build.
- evite usar
4. Integrar scanners e monitoramento contínuo
- Inclua no CI:
npm audit(ou equivalente para pnpm/yarn);- ferramentas de terceiros (Snyk, Socket.dev, Xygeni, etc., de acordo com sua realidade).
- Combine isso com alertas:
- PRs bloqueadas se vulnerabilidades críticas forem encontradas;
- relatórios periódicos de dependências mais arriscadas.
5. Isolar ambientes e limitar impacto
- Mantenha runners de CI minimamente isolados:
- privilégios mínimos;
- rotação de tokens;
- acesso restrito a recursos de produção.
- Trate qualquer incidente de supply chain como intrusão potencial:
- gire segredos;
- revise logs;
- valide integridade de artefatos publicados.
Conclusão: axios é só a ponta do iceberg
O caso do axios reforça algo que o incidente do CanisterWorm já tinha escancarado: o ponto fraco raramente é “apenas a sua aplicação”, e sim toda a cadeia de ferramentas que você escolhe trazer para dentro do seu build.
Hoje, fazer segurança em projetos JavaScript/Node significa:
- enxergar dependências como parte do seu attack surface;
- encarar
npm installcomo uma operação sensível; - automatizar o máximo possível as verificações de integridade e vulnerabilidades;
- criar políticas claras de versionamento, atualização e revisão de pacotes.
Se um pacote tão consolidado quanto o axios pode ser usado como vetor de ataque, qualquer outro também pode. A pergunta não é mais “isso vai acontecer?”, mas sim “quando acontecer, o quanto isso vai doer no meu ambiente?”
