1 pontos por GN⁺ 1 시간 전 | 1 comentários | Compartilhar no WhatsApp
  • Um ataque à cadeia de suprimentos do registro npm expôs milhões de aplicativos corporativos e bilhões de registros de usuários, mas o ecossistema trata isso como algo inevitável
  • O Senior Frontend Engineer Mark Vance critica a realidade de depender de 40 níveis de dependências aninhadas de pacotes não verificados até para transformar uma string em maiúsculas
  • A tomada de um pacote utilitário abandonado há muito tempo, com injeção de crypto-miner em builds de produção no mundo todo, é tratada como um desastre natural
  • O ecossistema Node.js encara uma execução remota de código maliciosa como uma tragédia imprevisível, enquanto equipes de DevOps ficam ocupadas trocando chaves da AWS
  • Os ecossistemas de Go, Rust e Web APIs nativas aparecem como contraste, com bibliotecas padrão fortes e verificação criptográfica para reduzir a dependência de terceiros

Sátira sobre ataque à cadeia de suprimentos no npm

  • Um ataque à cadeia de suprimentos do registro npm comprometeu milhões de aplicações corporativas e expôs bilhões de registros de usuários, mas os desenvolvedores do ecossistema JavaScript tratam isso como algo “completamente impossível de evitar”
  • O Senior Frontend Engineer Mark Vance vê como custo do desenvolvimento moderno de aplicações web a realidade de depender de uma árvore de 40 níveis de dependências aninhadas de pacotes não verificados só para colocar uma única string em maiúsculas
  • A tomada de um pacote utilitário abandonado há muito tempo, com a injeção de crypto-miner em builds de produção ao redor do mundo, é tratada como um desastre natural
  • O ecossistema Node.js encara uma execução remota de código maliciosa como uma tragédia imprevisível e envia “pensamentos e orações” às equipes de DevOps ocupadas em trocar chaves da AWS

Contraste entre outros ecossistemas e o npm

  • Os ecossistemas de Go, Rust e Web APIs nativas reduzem bastante a dependência de código de terceiros com bibliotecas padrão robustas e incluem verificação criptográfica rigorosa na cadeia principal de ferramentas
  • Nesses ecossistemas, o contraste é que hoje houve zero casos de um “projeto de fim de semana de um universitário que largou a faculdade” derrubando a infraestrutura logística global
  • Um porta-voz do npm afirmou de forma categórica que, em um mundo onde existem agentes maliciosos, isso precisa ser aceito, e que não há política de registro nem guardrails de sandbox de build capazes de impedir isso
  • O registro npm é retratado como um registro de código aberto que executa por padrão scripts de instalação arbitrários na máquina local, fazendo a fala do porta-voz se alinhar ao risco estrutural
  • No fim, o texto oferece consolo às vítimas, mas conclui dizendo que é preciso manter a resiliência até “a próxima violação inevitável” amanhã de manhã

1 comentários

 
GN⁺ 1 시간 전
Comentários no Hacker News
  • Cada um pode ter sua opinião sobre cooldown, mas boa parte dos ataques recentes à cadeia de suprimentos do npm, incluindo axios e tanstack, poderia ter sido evitada com cooldown
    Se você usa Artifactory / Nexus, provavelmente já tem algum cooldown; e, se não tiver, é fácil configurar
    Como a maioria das invasões ao npm ou ao PyPI foi removida em poucas horas, cooldown aqui quer dizer “ignorar pacotes lançados há menos de N dias”. Até 1 dia já ajuda, 3 dias é razoável e 7 dias é um pouco excessivo, mas funciona
    Para configurar isso, dá para usar a versão mais recente do pnpm, que já inclui cooldown padrão de 1 dia, ou https://pnpm.io/supply-chain-security; se quiser corrigir tudo de uma vez, pode usar https://depsguard.com, que adiciona cooldown e configurações recomendadas para npm, pnpm, yarn, bun, uv e dependabot. Eu sou o mantenedor
    Ou então há o https://cooldowns.dev, mais focado especificamente em cooldown, além de scripts para ajudar com configuração local. Tudo é open source ou gratuito
    Se você já sabe editar ~/.npmrc e afins manualmente, talvez nem precise disso, mas para pessoas próximas que precisam de uma solução com um clique, isso pode evitar o próximo ataque
    Claro, quando for preciso corrigir um CVE crítico novo, será necessário contornar o cooldown, e cada ferramenta tem sua forma de fazer isso. Não tenho números exatos, mas nas últimas semanas parece que o risco maior veio mais de ataques à cadeia de suprimentos de software do que de novos CVEs zero-day

    • Acho até estranho considerar 7 dias excessivo. A menos que você precise muito de algum recurso novo específico, mesmo ao começar um projeto novo normalmente já bastariam versões de dependências lançadas há alguns meses
      O mesmo vale para upgrades periódicos de dependências. Só que há casos em que é preciso atualizar imediatamente, como resposta a vulnerabilidades, e aí eu acho aceitável exigir que o desenvolvedor especifique explicitamente a nova versão desejada
    • Então isso não seria só empurrar o problema por 7 dias? Eu achava que esses incidentes acabam quando alguém é infectado e percebe, não porque exista um exército auditando mudanças e pegando o problema
      Se todo mundo aplicar um cooldown de 7 dias, isso não só vai explodir mais tarde?
    • Parece que faltou uma frase:

      Aviso: eu mantenho o depsguard

    • Não tenho certeza de que cooldown seja realmente eficaz. Alguém ainda precisa contornar o cooldown, instalar uma release potencialmente problemática e descobrir o problema. Se ninguém fizer isso, você só atrasou o problema em 3/7/10/14 dias
      Pensando melhor enquanto escrevo, ainda assim concordo com um cooldown de 10 dias, no sentido de não instalar nada lançado nos últimos 10 dias. Só não acho que isso deva ser tratado como a única mitigação
    • Não daria para criar distribuições ou canais separados, tipo latest/stable/LTS, como nas distribuições Linux?
  • Fico curioso sobre o que Go ou Rust realmente garantem em comparação com Python/npm. Também pode ser só que Python/npm sejam alvos mais atraentes
    Estou cada vez mais tentando evitar qualquer pacote de terceiros

    • A forma como a propriedade de pacotes e namespaces é atribuída depende 100% de quem opera o gerenciador de pacotes
      O Maven Central existe há décadas, mas teve pouquíssimos incidentes de roubo de namespace
      Você não pode publicar um pacote com groupId com.ycombinator sem verificar que possui o domínio ycombinator.com. E, uma vez publicado, o pacote é 100% imutável, mesmo que contenha código malicioso. Claro, essas bibliotecas passam a ser marcadas como vulneráveis em vários lugares
      Não entendo como o NPM não conseguiu copiar salvaguardas como as do Maven Central em todo esse tempo
    • Um dos pontos centrais do texto é que a maioria das outras linguagens populares tem uma biblioteca padrão abrangente. A biblioteca padrão do JS é surpreendentemente pequena
      Em vez de haver um conjunto de bibliotecas verificadas distribuídas com a linguagem, a aplicação precisa implementar por conta própria ou buscar em um repositório de pacotes de terceiros. Como passamos anos ensinando as pessoas a evitar NIH, elas acabam pegando um pacote
      Isso em si não é necessariamente ruim, mas muitas vezes puxa-se mais código do que o necessário. O ecossistema JS também favorece módulos pequenos, então são precisos muitos módulos, e todo mundo vai empilhando mais coisas por cima, fazendo o grafo de dependências ficar gigantesco. Seja por intenção ou não, a superfície para dar problema é enorme
      Outras linguagens já trazem muito mais coisa pronta. Não é que nunca tenham tido bugs ou problemas de segurança, mas, comparado ao que vemos no ecossistema JS, é quase nada. O grafo de dependências externas é muito menor, e as funções centrais vêm de terceiros confiáveis
    • Atacantes vão aonde estão as vítimas. O front-end chega perto de uma monocultura em que quase todo mundo usa NPM, enquanto no back-end isso é menos intenso
      Isso não serve de desculpa para o NPM; na verdade, é mais um fator contra ele
      Também daria para dizer que esse tipo de ataque evidencia ainda mais a diferença entre desenvolvedores front-end e back-end, mas não vou tão longe
    • Sinceramente, Rust também tem exatamente o mesmo padrão de ataque à cadeia de suprimentos. Só é mais novo e, por enquanto, está sendo melhor administrado. Espera mais 10 anos
    • Da última vez que vi, o npm tinha autenticação de dois fatores para publicação, mas o cargo não tinha. Não acho que o cargo seja especialmente melhor que o npm; só não é um alvo tão atraente
  • Em vários empregos, sofremos bastante para instalar configurações globais seguras do npm em todas as máquinas de desenvolvedores, pedir para as pessoas não desativarem isso e ainda verificar tudo com ferramentas de MDM
    Configurações padrão mais seguras já deveriam existir há muito tempo

    • É só não usar npm. Use um gerenciador de pacotes que não execute postinstall por padrão; a troca é incrivelmente simples
    • Fico me perguntando o que exatamente significa configuração segura. Se a ideia for impor cooldown ou listas de permissão/bloqueio de pacotes, a abordagem correta é a empresa configurar um repositório sob seu controle, buscar do repositório upstream do npm e aplicar as políticas desejadas
  • Não existe motivo legítimo para scripts de postinstall precisarem existir. A equipe do npm já amadureceu o suficiente para declarar algo como “a partir da versão tal do npm, scripts de postinstall só serão executados para versões de pacotes publicadas antes de ${today}”

    • Auditei recentemente vários scripts de postinstall de pacotes populares. A maioria fazia coisas como usar ou baixar binários nativos, detectar compatibilidade de plataforma, fazer a ligação manualmente em vez de deixar o Node cuidar do bootstrap, e contornar problemas de versões antigas do npm
      Isso acontece porque toolchains de desenvolvimento como esbuild são feitos em linguagens compiladas e distribuídos como binários via repositório npm. Se você usa Node/npm atual e um OS/plataforma recente comum, deveria ser possível desativar todos os scripts de postinstall sem prejuízo legítimo
    • Scripts de instalação, assim como assinatura de pacotes, são distrações. Adicionar ou remover qualquer um desses recursos não muda muito o potencial de esse ecossistema virar um worm
      Código instalado via npm quase sempre acaba sendo executado de qualquer forma
    • O fato de pacotes Rust poderem ser executados sem sandbox durante o build também não parece muito justificável
    • Isso não corrige de fato o problema. O código do pacote também é executado no momento do build e durante os testes. Dá para reduzir um pouco o escopo, mas é só isso
    • Falando com cuidado, scripts de postinstall são quase uma polêmica ilusória. As pessoas se assustam porque código controlado por terceiros está sendo executado no seu computador e pode fazer coisas ruins, e sim, pode mesmo
      Mas o mesmo vale para o código normal dentro do pacote. Mesmo que não rode no momento da instalação, em algum momento algo dali vai ser executado. Se não fosse assim, aquilo nem teria sido incluído como dependência
      Achar que remover scripts de postinstall vai ter mais que um efeito momentâneo na taxa de abuso é sinal de que o problema não foi pensado até o fim. Infelizmente, a questão é muito mais sutil do que o texto original sugere
      Não é um problema do tipo “não vamos colocar o botão que derruba as asas ao lado do interruptor de luz”; o ponto central é que não temos como distinguir “código ruim de outra pessoa rodando no meu computador” de “código bom de outra pessoa rodando no meu computador” sem um trabalho manual extremamente penoso. E executamos código de terceiros justamente para evitar esse trabalho manual penoso
  • Todo projeto Node.js começa com npm install, e de repente aparecem 500 pacotes que você nunca quis. Metade deles está sem manutenção há anos

  • Existe um problema cultural de querer atualizar até o que já funciona bem para a versão mais recente possível. Às vezes nem leem o changelog para ver se a mudança é relevante
    Cooldown é só uma forma de forçar um pouco de paciência nos mantenedores, e isso realmente ajuda

    • Se houver exigências de conformidade, você acaba tendo de atualizar por causa de CVEs reportados em versões antigas. A maioria é quase falsa, tipo “ReDoS em regex”, mas, para cumprir o processo, ainda assim é preciso atualizar
    • E também tem o caso de donos de pacotes atualizarem coisas que não precisavam de atualização só para não parecerem velhas e abandonadas
      Pacotes Lisp podem passar 15 anos sem mudanças e continuar ótimos, mas pacotes JS são tratados como se fosse um desastre estarem sem manutenção. Mesmo quando já estavam prontos 15 anos atrás, ainda assim recebem bump de versão sem adicionar nada — ou às vezes até com mudanças quebrando compatibilidade — só para parecer que estão sendo mantidos no npm e no GitHub. Aí tudo acaba sendo atualizado
  • Cooldown de 7 dias parece uma gambiarra de baixo esforço. A solução real provavelmente seria algo como builds reproduzíveis e atestados assinados, mas a maioria dos times não vai pagar esse custo até ser vítima primeiro

  • Isso parece um artigo do Onion

    residents of the Node.js ecosystem stood unified in their belief that the malicious remote-code execution was a completely unpredictable tragedy
    Tem mesmo alguém que acredita nisso? Já houve exemplos demais do contrário
    É uma boa sátira das falhas do ecossistema, mas no fim continua sendo entretenimento. Talvez até sirva de gancho para marqueteiros empurrarem seus produtos. Por exemplo, o mantenedor do depsguard apagou esse fato do próprio texto, depois recolocou, e depois apagou de novo. No momento em que escrevo isso, o post está no topo

  • Este link é claramente uma versão lavada por IA de uma piada que Xe Iaso já vinha fazendo há muito tempo. Que pena
    https://xeiaso.net/shitposts/no-way-to-prevent-this/CVE-2024...
    https://news.ycombinator.com/item?id=40438408