Il 20 agosto 2026 un attaccante ha compromesso l'account del manutentore di arrayref, una delle librerie fondamentali dell'ecosistema Rust, e ha pubblicato su crates.io una versione avvelenata. Nell'arco di ventitré minuti sono cadute anche internment e append-only-vec, mantenute dallo stesso account. Il codice sorgente delle librerie è rimasto identico: l'unica modifica è stata l'aggiunta di una dipendenza, e quella dipendenza esegue codice mentre il progetto viene compilato.

È una distinzione che conta. Non serve che il programma compromesso venga eseguito: basta lanciare cargo build.

I fatti

Le versioni malevole sono arrayref 0.3.10, internment 0.8.7 e append-only-vec 0.1.9. Tutte e tre dichiarano una dipendenza da proc-macro1, un pacchetto typosquat che imita il nome del diffusissimo proc-macro2. All'interno di proc-macro1 si trova uno script build.rs, eseguito automaticamente da Cargo durante la compilazione, che ricostruisce gli indirizzi della propria infrastruttura da frammenti codificati in base64 e scarica il payload corrispondente al sistema operativo dell'host. Sono previste build per Linux x86-64, Windows x86-64, macOS x86-64 e macOS ARM64.

Su sistemi Unix il malware scrive /tmp/rust-setup, lo rende eseguibile e lo lancia come processo distaccato. Su Windows crea %TEMP%\rust-setup.ps1 e usa wscript.exe con un launcher VBS in modalità nascosta. La persistenza è garantita tramite chiave Run del registro su Windows, LaunchAgent su macOS e unit systemd su Linux. Il secondo stadio, analizzato da Wiz, esfiltra informazioni sull'host e credenziali, incluse quelle estratte interrogando i database SQLite di Google Chrome, Brave ed Edge.

La cronologia ricostruita da StepSecurity è istruttiva quanto il codice. Alle 01:17 UTC viene creato un account GitHub che impersona David Tolnay, sviluppatore Rust molto noto, seguito da un account analogo su crates.io. Alle 01:55 viene pubblicato proc-macro1@1.0.106, una copia benigna di proc-macro2: serve a costruire una parvenza di legittimità. Alle 07:11 arriva la versione 1.0.107, malevola. Alle 07:15 viene pubblicata arrayref 0.3.10 dall'account legittimo del manutentore, e contestualmente vengono rimosse le versioni dalla 0.3.5 alla 0.3.9, presumibilmente per costringere i build a risolvere sulla release infetta. La segnalazione arriva alle 07:54; crates.io elimina proc-macro1 alle 08:03 e sfila arrayref 0.3.10 dall'indice alle 08:41.

La finestra di esposizione è stata di circa un'ora e mezza. Il bacino potenziale, però, è enorme: arrayref conta oltre 245 milioni di download complessivi e più di 53 milioni negli ultimi novanta giorni, mentre internment e append-only-vec sommano quasi 19 milioni di installazioni. Fra i progetti che la usano ci sono blake3, framework grafici come egui, eframe e iced, e componenti degli ecosistemi Ethereum e Solana. Wiz segnala che l'infrastruttura della campagna presenta sovrapposizioni con recenti attacchi alla supply chain attribuiti alla Corea del Nord, fra cui quelli ai pacchetti Mastra e axios.

Cosa significa per le aziende italiane

Chi non scrive Rust è tentato di considerare la notizia irrilevante. Vale la pena resistere alla tentazione, per tre ragioni.

La prima è che il vettore non è specifico di Rust. build.rs in Cargo, preinstall/postinstall in npm, setup.py in Python: sono tutti punti in cui il gestore di pacchetti esegue codice arbitrario prima ancora che qualcuno lanci l'applicazione. Le difese su cui la maggior parte delle organizzazioni italiane fa affidamento — l'antivirus sull'endpoint, il controllo del codice in code review, i test in staging — non intercettano nulla di tutto questo, perché l'esecuzione avviene sulla macchina dello sviluppatore o sul runner di CI, in un contesto che nessuno tratta come produzione ma che quasi sempre custodisce token di deploy, chiavi di firma e credenziali cloud.

La seconda è che la finestra di novanta minuti sposta il problema dalla prevenzione al rilevamento. Nessun processo di approvazione delle dipendenze, per quanto maturo, reagisce in un'ora e mezza. Ciò che fa la differenza è la capacità di rispondere a una domanda molto concreta a posteriori: quali nostre build, fra le 07:15 e le 08:41 UTC del 20 agosto, hanno risolto arrayref 0.3.10? Le organizzazioni che conservano i lockfile sotto version control e i log delle build sanno rispondere in dieci minuti. Le altre non lo sanno affatto, ed è questo, più della vulnerabilità in sé, il divario che gli attacchi alla supply chain mettono a nudo.

La terza ragione è normativa. Per i soggetti che ricadono in NIS2 la sicurezza della catena di approvvigionamento non è una buona pratica ma un obbligo esplicito dell'articolo 21: le dipendenze software di terze parti sono fornitori a tutti gli effetti, e la loro gestione va documentata. Per chi produce software destinato al mercato europeo si aggiunge il Cyber Resilience Act, che impone di mantenere una distinta dei materiali software e di gestire le vulnerabilità dei componenti per l'intero ciclo di vita del prodotto. Un incidente come questo è esattamente lo scenario su cui un'autorità di vigilanza, o un cliente enterprise che invia il proprio questionario NIS2, chiederà conto della procedura seguita. E se le credenziali esfiltrate includono accessi a sistemi che trattano dati personali, si apre in parallelo il capitolo dell'articolo 33 del GDPR e delle 72 ore per la notifica al Garante.

Cosa fare subito

Se avete build Rust, la verifica è puntuale e va fatta oggi:

  • Cercate le versioni incriminate nei lockfile: grep -rn -e 'arrayref' -e 'internment' -e 'append-only-vec' -e 'proc-macro1' Cargo.lock su tutti i repository, e controllate se compaiono rispettivamente 0.3.10, 0.8.7, 0.1.9 o qualunque versione di proc-macro1.
  • Verificate i file lasciati sul disco: /tmp/rust-setup su Linux e macOS, %TEMP%\rust-setup.ps1 su Windows.
  • Interrogate i log di rete alla ricerca di traffico verso 23.254.165.112 sulle porte 9089 e 443, nell'intervallo indicato.
  • In caso di riscontro positivo, presumete la compromissione della macchina, non del solo progetto: ruotate tutte le credenziali accessibili da quel sistema, i token di CI, le chiavi di firma e i segreti applicativi, e ricostruite l'ambiente da un backup sicuro. Le credenziali salvate nel browser vanno considerate perse.
  • Fissate le versioni sicure delle tre librerie finché la situazione degli account dei manutentori non sarà chiarita.

Sul piano strutturale, cioè per non ritrovarsi nella stessa posizione al prossimo episodio:

  • Attivate il ritardo di quarantena sulle nuove versioni nelle pipeline: molte organizzazioni impediscono l'ingresso di release pubblicate da meno di 24-72 ore, e in questo caso sarebbe stata una difesa completa a costo zero.
  • Eseguite le build in ambienti effimeri e isolati, con accesso di rete in uscita limitato a una allowlist di registry. Uno script build.rs che deve contattare un IP arbitrario fallisce.
  • Non lasciate segreti a lungo termine sui runner di CI: token a scadenza breve e federazione OIDC riducono drasticamente il valore di un compromesso di questo tipo.
  • Generate e conservate una SBOM per ogni build rilasciata. Serve proprio nelle mattine come quella del 20 agosto.