Todo npm install é um ato de confiança. Você já ficou olhando fixamente para o seu node_modules pasta e me perguntei: o que realmente tem aqui dentro? No desenvolvimento de software moderno, vivemos em um cenário peculiar em que somos responsáveis por um iceberg invisível de código que não escrevemos. Grande parte dele chega na forma de dependências transitivas, pacotes que ninguém da equipe escolheu diretamente. Quando esse código é enviado para produção, essa responsabilidade se transforma em ansiedade. SecureChain oferece uma camada de proteção para lidar com parte dessa pressão proveniente de terceiros.
O iceberg da dependência transitiva
Antes mesmo de instalar um pacote que aparece como dependência direta, você pode verificar as estrelas no GitHub, o perfil do mantenedor e os perfis dos colaboradores. A biblioteca raramente vem sozinha. Um pacote transitivo vem junto porque uma dependência direta o exige. Pense nisso como “pacotes dos seus pacotes”, ou até mesmo “pacotes dos pacotes dos seus pacotes”. Eles podem ter várias camadas de profundidade e permanecer intocados.
Esse iceberg é bem profundo, e o trocadilho é totalmente intencional. Um aplicativo web “básico” pode facilmente ultrapassar 1 mil pacotes armazenados no seu node_modules. As dependências transitivas ocultas nas camadas mais profundas são o local preferido para ataques à cadeia de suprimentos. Elas ampliam drasticamente o código de terceiros que você herda, e as auditorias manuais raramente chegam a esse nível de profundidade.
O problema não é que as dependências transitivas sejam ruins; o desenvolvimento moderno depende delas. O problema é que o código que você herda cresce mais rápido do que o código que você revisa.
Quando o malicioso parece legítimo
A ansiedade decorre desses pacotes que parecem legítimos, mas são, na verdade, maliciosos. Como desenvolvedores, recorremos bastante à memória muscular para realizar o trabalho. E agora, com a IA, o processo de realizar o trabalho nem mesmo exige mais isso. Os assistentes de programação, às vezes, sugerem nomes de pacotes que não existem. Isso abre um novo caminho chamado “slopsquatting”: registrar o nome que um modelo fica alucinando e aguardar.
A seguir, apresentamos uma lista de alguns dos mais comuns.
Typosquatting
Os ataques de “typosquatting” consistem em invasores que registram pacotes com nomes quase indistinguíveis de bibliotecas legítimas e populares, apostando que alguém digitará errado, lerá de forma superficial ou confiará em uma sugestão. Esses pacotes geralmente imitam a funcionalidade do alvo, de modo que nada parece estar errado à primeira vista. As táticas mais comuns incluem:
- Substituição de caracteres: Trocar letras, como em
lodashelodahs, um pacote realmente malicioso que tinha como alvo carteiras de criptomoedas. Os novos nomes do npm devem estar em letras minúsculas e ser compatíveis com URLs; por isso, os nomes semelhantes recorrem a truques que contornam essas regras, como um1em vez de uml. - Imitacão de namespace ou escopo: Registro de pacotes com escopo cujos nomes imitam de perto as bibliotecas oficiais, o que difere do ataque de resolução de registro descrito a seguir.
- Variações de formato: Utilizando técnicas de hifenização (por exemplo,
crossenvvs.cross-env) ou alterando a forma plural.
Como esses pacotes podem executar código arbitrário durante a instalação, eles podem roubar chaves de API, variáveis de ambiente ou credenciais da AWS antes que alguém examine o código-fonte.
Confusão de dependências
Os ataques de “confusão de dependências” têm como alvo organizações que utilizam uma combinação de registros públicos e privados. Um invasor pode explorar essa configuração publicando um pacote malicioso com o mesmo nome de um pacote interno, geralmente atribuindo a ele um número de versão mais alto. Se a sua configuração de compilação não estiver estritamente isolada, o sistema poderá resolver o nome do pacote como a versão pública do invasor, em vez da sua versão interna, executando automaticamente o código malicioso no momento da instalação.
Nada disso é mera teoria. Alex Birsan comprovou isso em 2021, ao publicar pacotes com nomes inspirados em bibliotecas internas e observar como eles eram resolvidos nos sistemas da Apple, da Microsoft e de dezenas de outras organizações.
Para quem não está familiarizado com o assunto, os pacotes com escopo (por exemplo, @my-org/cool-package) use um @ símbolo para dependências de namespace. A vulnerabilidade da sua organização geralmente depende de como você configura seu registro, escopo, proxies e arquivos de bloqueio. Os sistemas que nunca passaram por auditoria quanto a esses comportamentos de roteamento são os que correm maior risco. Para proteger seu pipeline, certifique-se de que a resolução de pacotes seja determinística. Mapeie escopos privados para o seu registro interno em .npmrc explicitamente, para que seu gerenciador de pacotes não resolva esse escopo de forma inesperada por meio do registro público:
@my-org:registry=https://registry.internal.example.com/
Reivindicar escopos correspondentes no npmjs.com também impede que invasores publiquem usando uma identidade que você já possui. Lembre-se de que o escopo é, antes de tudo, uma convenção de nomenclatura, e não um controle de segurança. Se o mesmo nome de dependência puder ser resolvido a partir de dois locais diferentes, outra pessoa acabará tomando essa decisão por você.
Scripts de ciclo de vida
Package.json ganchos de ciclo de vida, como preinstall, install,e postinstall são executados automaticamente durante a instalação das dependências, muito antes de alguém da equipe de desenvolvimento ter realmente verificado o que há neles.
Essas cargas úteis se direcionam aos alvos de maior valor: infraestrutura bancária, servidores de compilação e similares. Elas extraem segredos críticos, incluindo .env arquivos, tokens da AWS e chaves SSH: exatamente o que sempre nos dizem para nunca enviar para o controle de versão.
Certos scripts primeiro analisam o ambiente, verificando se há sandboxes ou sistemas sob vigilância rigorosa, e adiam a execução até chegarem a um local menos protegido.
Shai-Hulud mostrou a magnitude que isso atinge. A onda de setembro de 2025 utilizou postinstall para coletar tokens do npm e credenciais de nuvem em centenas de pacotes e, em seguida, se republicou com o que havia roubado. A onda de novembro antecipou a execução, levando-a para preinstall, de modo que o payload foi executado antes que a instalação fosse concluída. Variantes posteriores se ocultaram dentro de dependências opcionais, executando o payload e, em seguida, gerando uma falha de uma forma que o npm tolera.
Dito isso, o comportamento padrão finalmente mudou. pnpm A execução automática dos scripts do ciclo de vida das dependências foi interrompida na v10, na qual tudo o que precisa ser compilado deve estar listado em onlyBuiltDependencies. O npm v12, lançado em 8 de julho de 2026, adotou a mesma postura: os scripts de dependência não são executados a menos que o pacote raiz allowScripts a política os autorize, e npm approve-scripts --allow-scripts-pending lista tudo o que está aguardando uma decisão.
Mas há um porém. Um script não aprovado é ignorado com um aviso, e a instalação ainda retorna o código 0, o que pode deixar uma dependência nativa parcialmente compilada e causar uma falha posteriormente na sua compilação ou em tempo de execução. Faça o commit do allowScripts bloquear e definir strict-allow-scripts=true No CI, os scripts não revisados fazem com que a compilação falhe. Se você estiver usando o npm 11 ou uma versão anterior, o sinalizador abaixo resolve isso para você:
npm install --ignore-scripts
Útil, sim. Completo, não. Nada disso aborda a execução no momento da importação, e um pacote malicioso cujo código de nível superior é executado no momento em que seu aplicativo chama require() passa direto pelas proteções do script de instalação.
É colocada uma pressão enorme sobre nossos ombros quando se trata da responsabilidade pelo código que estamos lançando. No Relatório sobre o Panorama do Código Aberto de 2026 da TuxCare, entre os entrevistados cujas organizações relataram um incidente de segurança cibernética, 61,4% afirmaram que um patch estava DISPONÍVEL, mas nunca foi aplicado. Esse número deveria ser extremamente baixo. Saber que o risco existe não é o mesmo que eliminá-lo.
A profundidade das dependências torna isso mais difícil. Uma correção feita no upstream não tem efeito algum sobre a cópia fixada quatro níveis abaixo na sua árvore.
A revisão manual ainda faz parte do processo, mas auditar manualmente um gráfico desse tamanho não é viável. A falta de visibilidade sobre o que você está lançando pode, e certamente irá, comprometer sua pilha de sistemas.
Superando a ansiedade com o SecureChain
O gerenciamento do risco de dependências deve fazer parte da política. Realizar esse gerenciamento em grande escala pode sobrecarregar qualquer equipe. O SecureChain altera o caminho de consumo. Em vez de obter os pacotes diretamente do registro público, suas compilações os obtêm de um registro de pacotes gerenciado pela TuxCare, no qual os pacotes foram recompilados, assinados e corrigidos de acordo com um cronograma publicado.
Todo registro continua sendo uma decisão baseada na confiança. O que muda é que uma parte maior dessa confiança passa a ser verificável.
Fortificação de código-fonte
Cada pacote, incluindo as dependências transitivas, é recompilado a partir do código-fonte em ambientes isolados e reforçados e submetido a uma verificação para detectar malware conhecido e código suspeito, em vez de simplesmente redistribuir qualquer artefato publicado pelo desenvolvedor original.
Aplicação contínua de remendos
O SecureChain fornece correções, de acordo com o SLA, à medida que surgem CVEs. Para pacotes cujo ciclo de vida no upstream chega ao fim, o Endless Lifecycle Support (ELS) continua a fazer o backport de correções críticas e de alta gravidade para as versões que você já utiliza.
Configure seu gerenciador de pacotes para o SecureChain ou para o gerenciador de repositórios que você já utiliza, que é compatível com o Artifactory e o Nexus. O resultado são informações de proveniência criadas para oferecer conformidade verificável com o SLSA Nível 3, documentos VEX que indicam quais CVEs afetam uma versão do pacote e SBOMs legíveis por máquina para todos os componentes suportados, com cobertura em constante expansão. Nada disso substitui as boas práticas de segurança. Você ainda precisa de arquivos de bloqueio, regras de registro com escopo definido e credenciais de CI com privilégios mínimos.
Conclusão
Você pode diminuir um pouco a ansiedade ao lançar código que não foi escrito por você. A segurança é uma tarefa e uma política contínuas. Nunca se trata de uma mentalidade ou prática do tipo “configure e esqueça”. Compreender as dependências transitivas e reconhecer os problemas que delas decorrem ajudará você a lançar código de produção em boas condições.
O objetivo não é deixar de confiar no código aberto. Todos nós dependemos dele. O objetivo é deixar de tratar essa confiança como algo invisível.
O uso de ferramentas como o SecureChain pode aliviar um pouco desse fardo pesado que todos nós carregamos. Fique à frente do jogo e proteja SUA cadeia de suprimentos.
