Da npm a pnpm: guida alla migrazione post-breach axios

Contesto: il 31 marzo 2026 l’account npm del maintainer principale di axios (jasonsaayman) e’ stato compromesso. Le versioni axio 1.14.1 e 0.30.4 sono state pubblicate con una dipendenza malevola plain-crypto-js che eseguiva un RAT cross-platform via postinstall.

L’attacco ha sfruttato un token npm long-lived, bypassando la pipeline CI/CD GitHub Actions. La catena da npm install a beacon C2 richiedeva circa 15 secondi. Le versioni malevole sono rimaste live per circa 3 ore.

Cosa ci insegna questo attacco

Quello che possiamo imparare, prima di passare all’azione e’ che dobbiamo smetterla di dare per scontato che i tool che utilizziamo quotidianamente siano sicuri. E’ inutile spostare la nostra fiducia esclusivamente a tool alternativi perche’, per definizione, anche questi saranno vulnerabili in futuro. Dobbiamo partire dalla realta’ dei fatti, ovvero che non esistono sistemi sicuri, punto. E quindi come si evitano questa categoria di problemi e vulnerabilita’ in sede di sviluppo? La soluzione e’ cambiare i processi di sviluppo, non semplicemente un tool. Ieri era npm, domani sara’ bun e cosi’ via.

Rimuovere la superficie di attacco e’ l’unico modo per sviluppare serenamente

E rimuovere la superficie di attacco significa predisporre un sistema containerizzato, separato, isolato da quello che utilizziamo normalmente. Questo tra l’altro risolve tutta una serie di problematiche emerse dall’uso massivo di llm per sviluppare, anche loro estremamente rischiosi se lasciati nel nostro os. Come? Ci stiamo lavorando, ma sostanzialmente usando podman e similari. Per ora concentriamoci sul risolvere il problema immediato: smettiamo di usare npm.

Smetti di usare npm. Adesso.

Perche’ pnpm? Avrebbe davvero bloccato questo attacco specifico?

Il vettore primario era un postinstall nella dipendenza transitive plain-crypto-js.

Aspettonpm (default)pnpm v10+ (default)
Esecuzione postinstallAutomaticaBloccata di default
Dipendenze transitive flatAccessibiliIsolate (strict node_modules)
minimumReleaseAgeNon disponibileConfigurabile
trustPolicyNon disponibileRileva downgrade di trust
blockExoticSubdepsNon disponibileBlocca sorgenti “exotic”

Quindi?: Con pnpm (almeno da v10 in su) abbiamo un ottimo policy hardening, che avrebbe bloccato questo specifico attacco nel punto piu’ critico: la fase di postinstall.

Risolve tutto? Cosa pnpm non risolve?

Purtroppo no, non e’ una manna, ma per ora ci aiuta a facilitare il periodo di transizione alla containerizzazione di cui parlavamo prima.

  1. Lockfile avvelenato: se aggiornassimo il lockfile durante la finestra d’attacco, la versione compromessa rimarrebbe.
  2. Allow-list troppo ampia: un pacchetto autorizzato in allowBuilds potrebbe diventare vettore.
  3. Payload runtime: codice malevolo nel modulo non viene fermato magicamente.
  4. Compromissione registry: ricordiamoci che pnpm scarica dallo stesso npm registry di npm.

Step 0: verifica immediata

BASH_MANIFESTO

Se trovate tracce di tutto cio’, considerate la macchina compromessa: cambiate credenziali, invalidate token e rebuild completo da immagine pulita. Se e’ il vostro OS, per ora il consiglio degli esperti e’ la formattazione completa (si, hai letto bene, per aver eseguito npm install axios).

Step 1: installare pnpm

Versione stabile corrente: 10.33.x.

POWERSHELL_MANIFESTO

Nota Windows: Microsoft Defender puo’ rallentare installazioni massicce. Valutate una esclusione sullo store pnpm.

Step 2: configurazione sicura (pnpm-workspace.yaml)

YAML_MANIFESTO

Questa baseline riduce la finestra di rischio in modo concreto.

Step 3: tabella comandi prima/dopo

OperazionePRIMA (npm)DOPO (pnpm)
Installa dipendenzenpm installpnpm install
Installa un pacchettonpm install axiospnpm add axios
Dev dependencynpm install -D vitestpnpm add -D vitest
Disinstallanpm uninstall axiospnpm remove axios
Esegui scriptnpm run devpnpm dev
One-shotnpx some-toolpnpm dlx some-tool
CI lockfile immutabilenpm cipnpm install --frozen-lockfile

Step 4: workflow reali

4.1 Creare un progetto React con Vite

BASH_MANIFESTO

4.2 Installare Bootstrap

BASH_MANIFESTO

4.3 Installare axios (versione sicura)

BASH_MANIFESTO

4.4 Progetto Express

BASH_MANIFESTO

Codice applicativo invariato:

JAVASCRIPT_MANIFESTO

4.5 Migrare un progetto esistente da npm a pnpm

BASH_MANIFESTO

4.6 .gitignore

PLAINTEXT_MANIFESTO

4.7 package.json scripts

JSON_MANIFESTO

Step 5: quando pnpm vi protegge

Scenario A: postinstall non autorizzato

PLAINTEXT_MANIFESTO

Scenario B: pacchetto troppo recente

PLAINTEXT_MANIFESTO

Scenario C: downgrade di trust

PLAINTEXT_MANIFESTO

Regole d’oro

  1. pnpm add al posto di npm install per aggiungere dipendenze.
  2. pnpm install per installare dal lockfile.
  3. pnpm dev per gli script applicativi.
  4. pnpm dlx per tool one-shot.
  5. pnpm create per scaffold nuovi progetti.
  6. Sempre pnpm-workspace.yaml con policy esplicite.
  7. Sempre committare pnpm-lock.yaml.
  8. In CI usare pnpm install --frozen-lockfile.
  9. Il codice JavaScript/JSX applicativo non cambia col package manager.

Quick reference card

PLAINTEXT_MANIFESTO

Fonti