VibeInspect.aiBlog

Slopsquatting: l'agente AI installa pacchetti npm che non hai mai controllato

VibeInspect.ai · 3 settembre 2026 · 6 min di lettura

  • npm
  • dipendenze
  • slopsquatting
  • cursor
  • supply-chain

L'agente AI ha eseguito npm install mentre guardavi altrove

Per quindici anni la sicurezza dei pacchetti npm si è retta su un presupposto talmente ovvio da non essere mai stato scritto: tra la decisione di aggiungere una dipendenza e il momento in cui finisce sul disco c'era una persona. Gli assistenti di coding agentici hanno rimosso in silenzio quel controllo. Decidono che serve un pacchetto, ne scelgono uno e lanciano l'installazione a metà task, senza che nessuno riveda nulla.

È il punto sollevato da Maria nell'analisi "The npm install your AI agent ran while you weren't looking": una ricerca su 16 modelli linguistici ha generato due milioni di frammenti di codice e ha scoperto che quasi 1 pacchetto raccomandato su 5 semplicemente non esisteva. E i nomi inventati si ripetevano in modo prevedibile tra modelli e prompt diversi. Prevedibili abbastanza da essere registrati in anticipo. Questo attacco ha un nome: slopsquatting.

Il meccanismo è semplice e brutale. Un attaccante osserva quali nomi di pacchetti i modelli tendono ad allucinare, li registra su npm con dentro codice malevolo, e aspetta. Quando il tuo agente propone quel nome e lancia l'installazione, il payload è già lì. Nessuna interazione utente, nessuna pausa in cui qualcuno avrebbe potuto dire "aspetta, questo pacchetto non l'ho mai sentito".

Cosa significa se il tuo codice l'ha scritto Cursor

Se hai costruito la tua app dentro Cursor lasciando che l'agente gestisse le dipendenze, il tuo package.json non è più una lista che hai deciso tu riga per riga. È il risultato di scelte prese in autonomia durante decine di task diversi. E il problema non finisce con l'installazione: quel pacchetto, una volta dentro node_modules, può leggere variabili d'ambiente, aprire connessioni di rete, eseguire script in fase di postinstall.

Il rischio concreto per il tuo repository è la catena di dipendenze fuori controllo. Non parlo solo del pacchetto che l'agente ha scelto, ma di tutto ciò che quel pacchetto si porta dietro. Un solo nome allucinato e registrato da un malintenzionato può trascinare nel tuo build una manciata di dipendenze transitive che nessuno ha mai valutato. Se in quel codice ci sono le tue chiavi API, la stringa di connessione al database o il token del provider di pagamenti, hai appena dato a un estraneo un punto d'appoggio dentro il tuo processo.

Il guaio è che tutto questo non lascia tracce evidenti. L'app parte, i test passano, la demo funziona. Il problema vive nella distanza tra "ha funzionato" e "è sotto controllo", ed è esattamente lo spazio in cui gli agenti si muovono senza che tu te ne accorga.

Perché ora ti serve un audit

Quando fai vibe coding con un agente, tendi a giudicare il risultato dall'output visibile: la schermata gira, il flusso funziona, il cliente è contento. Ma le dipendenze non stanno nell'output visibile. Stanno nel manifesto del progetto, nel lockfile, negli script di installazione. Sono precisamente le parti che nessuno apre finché qualcosa non esplode.

Un audit serve a produrre un verdetto su ciò che non guardi mai. Con VibeInspect carichi lo ZIP del tuo repository, degli specialisti AI lo analizzano e ricevi un PDF con un giudizio chiaro. Nessun server coinvolto: il codice sorgente viene cancellato al termine dell'analisi. Non è un pentest, non corregge il codice e non promette sicurezza assoluta. Ti dice in che stato è davvero il tuo progetto.

Sul tema delle dipendenze, un audit ti mette davanti alle domande giuste. Quali pacchetti sono entrati senza una decisione consapevole? Ci sono nomi sospetti, tipografie strane, versioni che non corrispondono a niente di conosciuto? Ci sono script di postinstall che fanno cose che non ti aspetti? Ci sono segreti finiti nel codice a portata di qualsiasi dipendenza in esecuzione? Sono domande che non ti poni mentre l'agente lavora, perché il tuo obiettivo in quel momento è far girare la feature.

Con il piano Diagnostic ottieni file, riga ed evidenze puntuali: sai esattamente dove guardare, quale dipendenza mettere in discussione, quale punto del build merita attenzione. Non è una revisione umana e non ti riscrive il codice, ma ti dà la mappa che oggi ti manca.

Cosa un linter non vede

È il momento di sfatare un equivoco. Molti pensano che con ESLint e un paio di regole configurate il problema sia coperto. Non lo è. Un linter analizza lo stile e la correttezza sintattica del codice che scrivi tu. Non ha opinioni sul fatto che un pacchetto in package.json sia legittimo o sia un nome allucinato registrato ieri da un attaccante.

Un linter non verifica la reputazione di una dipendenza. Non nota che un pacchetto è stato pubblicato tre giorni fa, ha zero download reali e un nome sospettosamente simile a una libreria popolare. Non ispeziona cosa fa uno script di postinstall. Non collega la presenza di un segreto nel codice al fatto che una dipendenza qualsiasi, in esecuzione, potrebbe leggerlo ed esfiltrarlo.

Lo stesso vale per il resto della superficie di attacco che gli agenti hanno aperto. La ricerca citata segnala anche una vulnerabilità critica di tipo RCE in un componente ampiamente usato per collegare i modelli a server esterni: il codice malevolo può scattare nel momento in cui il client si connette a un server non fidato, connessione che l'agente stabilisce da solo, senza chiederti nulla. Nessuno strumento pensato per lo stile del codice intercetta un problema del genere. È una categoria di rischio diversa, e va guardata con strumenti diversi.

In breve: il linter risponde alla domanda "il mio codice è scritto bene?". L'audit risponde alla domanda "il mio progetto, con tutto ciò che si è portato dentro, è in uno stato affidabile?". Sono due domande distinte e la seconda, oggi, pesa di più.

Cosa fare questa settimana

Non serve smontare il progetto. Servono tre passaggi concreti.

Primo: apri il tuo package.json e il lockfile e leggi la lista delle dipendenze una per una. Per ogni nome che non riconosci, chiediti se sei stato tu a deciderlo o se l'ha aggiunto l'agente. Cerca il pacchetto su npm e controlla data di pubblicazione, numero di download e presenza di codice sorgente pubblico.

Secondo: verifica che non ci siano segreti nel codice. Chiavi, token, stringhe di connessione: se sono nel repository, qualsiasi dipendenza in esecuzione può raggiungerli. Spostali in variabili d'ambiente e ruota quelli che sono già stati esposti.

Terzo: ottieni un verdetto indipendente sullo stato del tuo repository. Carica lo ZIP su VibeInspect e lascia che l'analisi ti indichi con file e riga dove si annidano dipendenze sospette, segreti esposti e punti fragili nel build. È il modo più rapido per trasformare "speriamo vada bene" in "so cosa correggere per primo".

Hai usato l'AI per andare veloce. Bene. Ora dai al tuo codice il controllo che l'agente ha saltato. Avvia un audit Diagnostic con VibeInspect e scopri quali dipendenze meritano una seconda occhiata prima che sia un problema di produzione.

Domande frequenti

Cos'è lo slopsquatting?

È un attacco che sfrutta i nomi di pacchetti che i modelli AI tendono a inventare. Gli attaccanti registrano in anticipo quei nomi su npm con dentro codice malevolo, così quando l'agente li propone e li installa il payload è già presente.

Il mio linter mi protegge dalle dipendenze sospette?

No. Un linter controlla stile e sintassi del codice che scrivi tu. Non valuta la reputazione di un pacchetto, non ispeziona gli script di postinstall e non nota nomi allucinati registrati da poco.

VibeInspect corregge le dipendenze pericolose?

No. VibeInspect non corregge il codice e non è un pentest. Ti fornisce un verdetto con evidenze: nel piano Diagnostic ricevi file, riga e i punti da rivedere, così sai da dove partire.

Cosa devo controllare per primo nel mio repository?

Apri package.json e il lockfile, verifica ogni dipendenza che non hai scelto consapevolmente e assicurati che non ci siano segreti nel codice raggiungibili da un pacchetto in esecuzione.