Explorando novas formas de ataques de confusão de dependências por meio de aliases de pacotes npm
Nishant Jain
4 de novembro de 2021
0 minutos de leituraOs ataques de confusão de dependências são um tipo de ataque à segurança da cadeia de suprimentos de software de código aberto em que um invasor explora a forma como os gerenciadores de pacotes instalam dependências. Em um artigo anterior, explicamos como detectar e prevenir ataques de confusão de dependências no npm para manter a segurança da cadeia de suprimentos.
Neste artigo, apresentamos uma variação do problema de confusão de dependências que explora os recursos de criação de aliases de pacotes do npm. Esse recurso, disponibilizado e documentado pela interface de linha de comando do npm, permite que apenas o usuário instale um pacote com outro alias. Conforme a documentação oficial do npm, veja o exemplo a seguir:
Isso cria a seguinte entrada em package.json:
As consequências do uso de aliases de pacotes npm ficam evidentes na forma como outras ferramentas relacionadas a pacotes lidam com manifestos e, na verdade, também se aplicam ao próprio registro oficial npmjs.org. Embora esse cenário de ataque não tenha consequências diretas para a segurança (porque o pacote com alias sempre baixaria a versão especificada no comando npm), acreditamos que ele abre espaço para outros vetores de ataque.
Como executar um ataque com aliases de pacotes npm
Vamos reproduzir o impacto dos ataques com aliases de pacotes npm para demonstrar como eles podem levar à possível confusão de dependências e à instalação de pacotes maliciosos.
Começamos criando um pacote chamado deneuve-package-parent que instala duas versões diferentes do pacote deneuve-package-test: as versões 1.0.0 e 1.2.0. A versão 1.0.0 é instalada porque recebe o alias de um pacote fictício chamado deneuve-package-private, graças ao recurso de aliases de pacotes do npm.
No npmjs.com, isso é interpretado como uma das dependências de deneuve-package-parent.
Veja o package.json a seguir como referência completa da árvore de dependências descrita acima:
Publicamos o pacote no npmjs e, em seguida, acessamos a lista de dependências.
Como você pode ver, a lista de dependências do registro npmjs mostra o alias fictício deneuve-package-private como nome de uma das dependências:

A captura de tela acima mostra uma dependência chamada deneuve-package-private, que criamos como alias em nosso package.json, e não como uma dependência real. Esse alias (usado como nome de pacote) não existe de fato no registro npmjs — a menos que alguém o publique! E é aí que surgem as preocupações com a segurança da cadeia de suprimentos.

Isso levanta a seguinte questão: e se alguém encontrasse esses pacotes com alias e os publicasse como pacotes maliciosos no npm? Usuários desavisados poderiam ver uma dependência listada na página oficial de um pacote no npmjs e instalá-la simplesmente executando um comando npm install local na máquina de desenvolvimento:
Esse cenário pode ocorrer quando um desenvolvedor decide depurar a aplicação e baixar cada biblioteca individualmente. Vamos ser sinceros: com que frequência os desenvolvedores verificam se o pacote que estão baixando deveria ser privado? Basta um simples erro ou descuido, algo que pode acontecer mesmo em empresas com políticas contra o download de pacotes sem escopo.
Publicamos um pacote vazio com esse nome no registro npmjs. Como você pode ver, ao acessar a aba Dependents, ela aponta para o pacote original que o mencionou como alias entre as dependências:

Isso deve servir de alerta para todas as ferramentas de desenvolvimento que lidam com nomes de pacotes, incluindo o próprio registro npmjs, para que não confundam os usuários em relação aos nomes dos pacotes.
O fato de que nomes de pacotes com erros de digitação ainda são um vetor eficaz de ataques à cadeia de suprimentos demonstra que até mesmo uma pequena aparência de legitimidade (como a criada pelos aliases de pacotes) pode aumentar significativamente as chances de sucesso de um ataque.
Um pouco mais sobre essa descoberta
Essa forma de ataque à cadeia de suprimentos foi descoberta recentemente por mim e pelo pesquisador de segurança Mario Stathako, e a reportamos ao GitHub e ao npm. Sou estudante de pós-graduação e venho pesquisando e desenvolvendo recursos de segurança para programas de recompensa por bugs. Também sou embaixador da Snyk! Mario é testador de invasão e participa regularmente de competições Capture the Flag (CTF) e programas de recompensa por bugs.
A confusão de dependências chamou minha atenção porque era algo tão básico e, ao mesmo tempo, tinha um impacto enorme! Então, Mario e eu começamos a procurar esse problema nos programas privados da HackerOne. Queríamos ver como as empresas respondiam e mitigavam pesquisas populares depois de um período específico. Ao criar pacotes de prova de conceito (POC) para os ataques, encontramos um comportamento estranho no site do NPM: a forma como o arquivo package.json era processado para diferentes pacotes e como as dependências e os pacotes que dependiam deles eram listados.
Proteja-se contra riscos à segurança da cadeia de suprimentos
A Snyk desenvolveu e publicou uma ferramenta de linha de comando de código aberto chamada snync para ajudar você a detectar e receber alertas sobre possíveis ataques de confusão de dependências e ataques relacionados. Saiba tudo sobre a ferramenta neste artigo sobre detecção e prevenção de ataques de confusão de dependências no npm.
Além disso, o Snyk Advisor é uma ferramenta útil para sinalizar problemas de segurança em pacotes e em suas diferentes versões. Ela também mostra explicitamente se um pacote foi identificado como malicioso:

Para concluir, veja algumas leituras recomendadas sobre as boas práticas de segurança da cadeia de suprimentos de software de código aberto:
Comece a resolver desafios de capture the flag
Aprenda a resolver desafios de capture the flag assistindo sob demanda ao nosso workshop virtual introdutório.
