Skip to content

Recente hack di ESLint o come possiamo proteggerci dall'installazione di pacchetti npm dannosi?

Apprezziamo il tuo aiuto per estendere le nostre cronache sull'informatica.

Soluzione:

Tre parole: Gestione della catena di approvvigionamento. Solo che nel nostro caso la "fornitura" è la dipendenza o "librerie di terze parti".

Questo non è un problema esclusivo di npm. È un problema generale nello sviluppo del software. È l'equivalente di cercare su Google un produttore di "viti", poi usare il primo produttore di "viti" che si vede, non chiedere le specifiche delle "viti", poi usare queste "viti" e sperare che facciano bene il loro lavoro e che non si rompano, non si erodano/arrugginiscano troppo velocemente e che siano in grado di sopportare lo sforzo... senza aver mai controllato se quelle viti sono state testate, se hanno un adeguato controllo di qualità.
Possiamo farlo perché di solito non muoiono persone se il vostro software è difettoso o vulnerabile. Se una struttura crolla perché le viti sono difettose... è un'altra storia. Lì c'è responsabilità. Non c'è questa responsabilità nel software... tranne quando si lavora in alcune industrie in cui sono in gioco vite umane quando si verificano bug nel software o quando macchinari enormi e costosi si rompono (e/o mettono in pericolo vite umane) se il software di controllo è difettoso. E lo dico seriamente. Non si può semplicemente usare una libreria di terze parti senza un controllo rigoroso su un dispositivo incorporato che controlla macchine pericolose se si deve essere in grado di sostenere la comunicazione in tempo reale per controllare un processo in tempo reale e tutto va a rotoli se la libreria di terze parti che si usa produce un errore della CPU perché è difettosa... perché allora la macchina si danneggia davvero.

Il problema dello sviluppo del software è che "cerchiamo su Google" "qualche libreria" che fornisca "qualche funzionalità" e poi ci limitiamo a "npm install", "go get", "pip install" e siamo contenti. Non c'è alcun processo di verifica. Come si fa a sapere che il pacchetto fornisce ciò che dichiara? Sapete quanto è stato testato? Sapete se viene ancora mantenuto attivamente? Sapete quali sono le garanzie di stabilità delle API? Si può "andare a prendere" un pacchetto che una settimana dopo è completamente rotto, perché anche il codice che sembra "ufficiale" potrebbe non avere alcuna garanzia di stabilità delle API.

Quali vincoli di versione utilizzate? foo >= 1.5. Cosa succede se foo >= 1.6 introduce una backdoor? Chi compila il vostro codice con le versioni più recenti avrà questa backdoor. E se si usa foo == 1.5 ma ci sono diversi mirror e il mirror che il vostro collega usa per compilare il vostro software contiene una versione dannosa del pacchetto? E non dimenticate: se installate/utilizzate un pacchetto/libreria? Non dovete solo verificare quel pacchetto/libreria... dovete anche verificare l'intero albero delle dipendenze.

Avremmo bisogno di un processo di certificazione. Una volta che un'azienda/sviluppatore pensa che il suo pacchetto sia pronto, lo pubblica e poi società indipendenti di revisione del codice e di sicurezza lo esaminano e una volta che c'è un ragionevole grado di fiducia che questo pacchetto sia "sicuro" da usare, lo firmano. Quindi si possono usare solo le dipendenze che sono firmate e si usano gli hash oltre alle versioni, come ad esempio foo == ("1.5", "abc734defef373f..").

Come si applica questo a npm?

Non installare i pacchetti npm senza una revisione. Chi è l'autore? Qual è la qualità generale del codice? Quando è stato aggiornato l'ultima volta? Quali sono stati gli ultimi commit? Cosa fa l'installazione? Ha dei test adeguati? Qual è la copertura del codice e dei test? Quante persone lo usano? Chi lo sta usando?

Lo sviluppo del software si concentra sulla fornitura di aggiornamenti, nuove cose, aggiornamenti, nuove cose. Un test adeguato e una corretta "gestione del codice di terze parti" costano MOLTO e di solito né le aziende né i consumatori sono disposti a pagare questo prezzo. Dopo tutto, si tratta sempre di "rischio contro costo". Se il costo di una vulnerabilità di sicurezza è il furto delle credenziali di alcuni utenti... non interessa a nessuno. Non possono farvi causa... al massimo vi costa un po' di "immagine pubblica". Se il peggio è un software buggato che non funziona per alcuni utenti... potete permettervi qualche incazzatura da parte di utenti che comunque utilizzavano la versione gratuita...
Questo probabilmente cambierebbe se ci fosse una cosa come la "garanzia" per il software e la responsabilità per i bug del software (che in un certo senso esiste per quando paghi qualcuno per scrivere qualcosa per te), ma dal momento che molto software è open source che viene fornito con esattamente zero garanzie (questo è in realtà uno dei principali svantaggi di questo) o è un software che si sta utilizzando gratuitamente questo semplicemente non accadrà per quel tipo di software.

Questo problema esiste anche per l'utilizzo di javascript di terze parti sul proprio sito web. È la stessa cosa. I problemi sono quasi completamente gli stessi, indipendentemente dal linguaggio, dal framework e dalla tecnologia che si utilizza: Se volete essere sicuri... dovete verificare il codice di terze parti.

Un'altra cosa:

Ci sono pacchetti/librerie che forniscono solo piccole utilità... cose che si potrebbero scrivere da soli in 3h... forse un giorno. Questo non è un problema se non ci si preoccupa di più dipendenze (e più dipendenze complicano la gestione delle dipendenze), ma se lo si fa... a volte è davvero meno faticoso non usare queste semplici librerie e scrivere la funzionalità da soli, in modo da avere il pieno controllo su di essa e poterla testare correttamente. La regola generale è che se ci vuole più tempo per verificare il codice di qualcun altro che per scriverlo da soli... allora scrivetelo da soli. Questo vale anche se avete bisogno solo di una o due funzioni di un intero framework. È molto più facile verificare correttamente le due versioni di una funzione piuttosto che includere e verificare un intero framework, perché i framework stessi hanno delle dipendenze e bisogna verificare anche quelle.

A parte questo: ... si potrebbe bloccare il traffico verso i siti web non inseriti nella white list durante il processo di installazione, il che significa che questo attacco specifico non funzionerebbe, ma questo non funziona contro gli script di installazione dannosi che cancellano file a caso o inseriscono backdoor in file esistenti o altro. Dovrete leggere attentamente gli script di installazione.

La gestione della catena di distribuzione è la risposta giusta in teoria, tuttavia, nonostante gli sforzi di entità commerciali come snyk e molti altri, non esiste una soluzione a questo problema nell'ecosistema dei nodi in pratica.

La catena di approvvigionamento di Node, senza mancare di rispetto alle numerose persone che lavorano per migliorarla, è unica e terribile. Il re di quella montagna infame erano i moduli di wordpress, ma ora è node almeno da qualche anno. I difetti di sicurezza sono solo un costo del lavoro.

In teoria si può:

  • leggere tutto il codice delle dipendenze prima di installarle
  • leggere tutto il codice delle loro dipendenze
  • installare in sandbox con whitelist di server
  • inserire le dipendenze in whitelist, richiedendo un periodo di infornata di settimane o più
  • inserire feed di vulnerabilità, scanner e analizzatori
  • supporre che le postazioni di lavoro dei tecnici dei nodi siano sempre compromesse, utilizzare la gestione dei segreti e non consentire loro di vedere le password o di accedere direttamente ai sistemi o ai dati di produzione.
  • avere un CI/CD in grado di trovare e distribuire nuovamente tutte le applicazioni che consumano una specifica dipendenza quando vengono annunciate le correzioni

Oppure si può fare un po' di lavoro e sperare per il meglio finché l'ecosistema non migliora (e prima o poi lo farà).

Fondamentalmente il problema è che un software di terze parti ha cercato di rubare informazioni private e di inviarle in rete. Questo problema non è esclusivo di npm, qualsiasi software in esecuzione come utente del computer potrebbe fare lo stesso, dato che non c'è nulla che gli impedisca di leggere i dati dell'utente.

enter image description here

Come linea di difesa contro questo tipo di attacco, si potrebbe prendere in considerazione l'utilizzo di un firewall in uscita.

Esistono numerosi prodotti di questo tipo, per lo più commerciali, ma per il noto Little Snitch (di cui non sono affiliato), se il processo Node tenta di connettersi a un host a cui il firewall non è stato configurato per dare il permesso di accedere, all'utente viene richiesto di decidere se la connessione deve essere consentita, come in questo caso:

enter image description here

Naturalmente, se si vedesse qualcosa di simile durante l'installazione di un modulo npm, dovrebbe scattare qualche segnale di allarme e si potrebbe interrompere il processo a questo punto, negando l'accesso fino a quando non si verifica la fonte di questa connessione.

Ovviamente questo non sostituisce l'audit del codice sorgente, ma offre un ulteriore livello di difesa contro il software illegale che tenta di esfiltrare i vostri dati privati a livello di sistema e sarebbe probabilmente molto efficace nel fermare un attacco come questo (supponendo di non dare ai binari utilizzati dall'attacco permessi troppo generosi).

Se ritieni che questo post sia stato utile, ti saremmo grati se lo condividessi con più programmatori in questo modo contribuisci ad estendere questo contenuto.



Utilizzate il nostro motore di ricerca

Ricerca
Generic filters

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.