Quanto sono sicure le dipendenze open source di JavaScript?

Gli sviluppatori di JavaScript di oggi amano gli npm. GitHub e il registro di NPM sono lo spazio di prima scelta per gli sviluppatori per la ricerca di un particolare pacchetto. I moduli open source aumentano la produttività e l'efficienza fornendo agli sviluppatori una serie di funzionalità che è possibile riutilizzare nel proprio progetto. È giusto dire che se non fosse per questi pacchetti open source, la maggior parte delle strutture oggi non esisterebbe nella loro forma attuale.

Un'applicazione a livello enterprise a tutti gli effetti, ad esempio, potrebbe fare affidamento su centinaia se non su migliaia di pacchetti. Le solite dipendenze includono dipendenze dirette, dipendenze di sviluppo, dipendenze in bundle, dipendenze di produzione e dipendenze opzionali. È fantastico perché tutti stanno ottenendo il meglio dall'ecosistema open-source.

Tuttavia, uno dei fattori che vengono trascurati è la quantità di rischio coinvolto. Sebbene questi moduli di terze parti siano particolarmente utili nel loro dominio, introducono anche alcuni rischi per la sicurezza nell'applicazione.

Le librerie Open-Source sono vulnerabili?

Le dipendenze OSS sono effettivamente vulnerabili agli exploit e ai compromessi. Diamo un'occhiata ad alcuni esempi: 

Recentemente è stata scoperta una vulnerabilità in un pacchetto chiamato eslint-scope che è una dipendenza di numerosi pacchetti JavaScript popolari come babel-eslint e webpack. L'account del manutentore del pacchetto è stato compromesso e gli hacker hanno aggiunto del codice dannoso. Fortunatamente, qualcuno ha scoperto l'exploit abbastanza presto che il danno era riferito a pochi utenti. 

Moment.js, che è una delle librerie più utilizzate per l'analisi e la visualizzazione delle date in JavaScript, è stata recentemente riscontrata una vulnerabilità con un punteggio di gravità di 7,5. L'exploit lo rendeva vulnerabile agli attacchi ReDoS. Le patch sono state rilasciate rapidamente e sono state in grado di risolvere il problema piuttosto rapidamente.

Ma non è tutto. Un sacco di nuovi exploit vengono portati alla luce ogni settimana. Alcuni di loro vengono divulgati al pubblico, ma altri fanno notizia solo dopo una grave violazione. 

Quindi, come attenuiamo questi rischi? In questo articolo, spiegherò alcune delle migliori pratiche standard del settore che è possibile utilizzare per proteggere le proprie dipendenze open-source.

1. Tenere traccia delle dipendenze dell'applicazione

A livello logico, con l'aumento del numero di dipendenze, aumenta anche il rischio di finire con un pacchetto vulnerabile. Ciò vale anche per le dipendenze dirette e indirette. Sebbene non vi sia alcun motivo per cui dovresti smettere di usare i pacchetti open source, è sempre una buona idea tenerne traccia.

Queste dipendenze sono facilmente individuabili e possono essere semplici come l'esecuzione npm ls nella directory principale della tua applicazione. Puoi usare il -pungolo argomento che mostra tutte le dipendenze di produzione e il -lungo argomento per un riassunto di ogni descrizione del pacchetto. 

Inoltre, è possibile utilizzare un servizio per automatizzare il processo di gestione delle dipendenze che offre monitoraggio in tempo reale e test di aggiornamento automatico per le proprie dipendenze. Alcuni degli strumenti familiari includono GreenKeeper, Libraries.io, ecc. Questi strumenti raccolgono un elenco delle dipendenze attualmente in uso e tengono traccia delle informazioni pertinenti che li riguardano.

2. Sbarazzati di pacchetti che non ti servono

Con il passare del tempo e le modifiche nel codice, è probabile che smetterai di utilizzare alcuni pacchetti del tutto e invece ne aggiungerai di nuovi. Tuttavia, gli sviluppatori tendono a non rimuovere i vecchi pacchetti man mano che vanno avanti.

Nel tempo, il tuo progetto potrebbe accumulare molte dipendenze inutilizzate. Sebbene questo non sia un rischio diretto per la sicurezza, queste dipendenze quasi sicuramente si aggiungono alla superficie di attacco del tuo progetto e portano a una confusione non necessaria nel codice. Un utente malintenzionato potrebbe trovare una scappatoia caricando un pacchetto vecchio ma installato con un quoziente di vulnerabilità più elevato, aumentando così il potenziale danno che può causare.

Come si controllano tali dipendenze non utilizzate? Puoi farlo con l'aiuto dello strumento depcheck. Depcheck esegue la scansione dell'intero codice per richiede e importare comandi. Quindi mette in correlazione questi comandi con i pacchetti installati o quelli menzionati nel tuo package.json e ti fornisce un rapporto. Il comando può anche essere modificato utilizzando diversi flag di comando, rendendo così più semplice automatizzare il controllo delle dipendenze non utilizzate.

Installa depcheck con:

npm install -g depcheck

3. Trova e correggi le vulnerabilità di sicurezza cruciale

Quasi tutti i punti discussi sopra riguardano principalmente i potenziali problemi che potresti incontrare. Ma per quanto riguarda le dipendenze che stai usando in questo momento?

Sulla base di uno studio recente, quasi il 15% dei pacchetti correnti include una vulnerabilità nota, sia nei componenti che nelle dipendenze. Tuttavia, la buona notizia è che ci sono molti strumenti che è possibile utilizzare per analizzare il codice e individuare i rischi per la sicurezza open source all'interno del progetto.

Lo strumento più conveniente è quello di npm audit npm. Audit è uno script che è stato rilasciato con la versione 6 di npm. Node Security Platform inizialmente ha sviluppato l'audit di npm e il registro di NPM lo ha acquisito in seguito. Se sei curioso di sapere che cos'è l'audit di npm, ecco una citazione dal blog ufficiale:

Un controllo di sicurezza è una valutazione delle dipendenze del pacchetto per le vulnerabilità della sicurezza. I controlli di sicurezza aiutano a proteggere gli utenti del pacchetto consentendo di trovare e correggere vulnerabilità note nelle dipendenze. Il comando di controllo npm invia una descrizione delle dipendenze configurate nel pacchetto al registro predefinito e richiede un report di vulnerabilità note. 

Il report generato solitamente comprende i seguenti dettagli: nome del pacchetto interessato, gravità della vulnerabilità e descrizione, percorso e altre informazioni e, se disponibili, comandi per applicare le patch per risolvere le vulnerabilità. È anche possibile ottenere il rapporto di controllo in JSON eseguendo audit npm --json.

Oltre a questo, npm offre anche assistenza su come agire in base al rapporto. Puoi usare Correzione di controllo di npm per risolvere problemi che sono già stati trovati. Queste correzioni vengono comunemente eseguite utilizzando gli aggiornamenti guidati o tramite patch open source. 

Sentiti libero di consultare la documentazione di npm per maggiori informazioni.

4. Sostituire le librerie scadute con le alternative interne 

Il concetto di sicurezza open source è fortemente dipendente dal numero di occhi che stanno guardando su quella particolare libreria. I pacchetti che vengono utilizzati attivamente sono osservati più da vicino. Pertanto, c'è una maggiore possibilità che lo sviluppatore possa aver risolto tutti i noti problemi di sicurezza in quel particolare pacchetto. 

Facciamo un esempio. Su GitHub ci sono molte implementazioni di token web JSON che puoi usare con la tua libreria Node.js. Tuttavia, quelli che non sono in sviluppo attivo potrebbero avere vulnerabilità critiche. Una di queste vulnerabilità, che è stata segnalata da Auth0, consente a chiunque di creare i propri token "firmati" con qualsiasi payload che desiderano. 

Se un pacchetto ragionevolmente popolare o ben utilizzato avesse questo difetto, le probabilità che uno sviluppatore trovasse e aggiustassero l'errore sarebbero più alte. Ma che dire di un progetto inattivo / abbandonato? Ne parleremo nel prossimo punto.

5. Scegli sempre una libreria che si trova nello sviluppo attivo

Forse il modo più rapido ed efficiente per determinare l'attività di un pacchetto specifico è controllare la velocità di download su npm. Puoi trovarlo nel Statistiche sezione della pagina del pacchetto di npm. È anche possibile estrarre queste cifre automaticamente utilizzando l'API di statistiche npm o sfogliando le statistiche storiche su npm-stat.com. Per i pacchetti con repository GitHub, dovresti controllare la cronologia dei commit, il tracker dei problemi e qualsiasi richiesta di pull rilevante per la libreria.

6. Aggiornare frequentemente le dipendenze

Ci sono molti bug, incluso un gran numero di bug di sicurezza che vengono continuamente portati alla luce e, nella maggior parte dei casi, immediatamente rattoppati. Non è raro vedere le vulnerabilità segnalate di recente essere fissate esclusivamente sulla succursale / versione più recente di un determinato progetto.

Ad esempio, prendiamo la vulnerabilità di Denial of Service (ReDoS) di Expression Regular riportata sul pacchetto HMAC "hawk" all'inizio del 2016. Questo bug in falco è stato risolto rapidamente, ma solo nell'ultima versione principale, 4.x. Le versioni precedenti come 3.x sono state patchate molto più tardi anche se erano ugualmente a rischio. 

Pertanto, come regola generale, le tue dipendenze hanno meno probabilità di avere problemi di sicurezza se utilizzano l'ultima versione disponibile. 

Il modo più semplice per confermare se stai utilizzando l'ultima versione è utilizzando il npm obsoleto comando. Questo comando supporta il -pungolo flag per ignorare qualsiasi dipendenza di dev e --jSON per rendere l'automazione più semplice.

Ispeziona regolarmente i pacchetti che utilizzi per verificare la loro data di modifica. Puoi farlo in due modi: tramite l'interfaccia utente di npm o eseguendo vista npm time.modified.

Conclusione

La chiave per garantire la tua applicazione è quella di avere una cultura della sicurezza fin dall'inizio. In questo post, abbiamo trattato alcune delle pratiche standard per migliorare la sicurezza dei componenti JavaScript. 

  1. Utilizza le dipendenze open source che sono in sviluppo attivo.
  2. Aggiorna e controlla i tuoi componenti.
  3. Controlla il tuo codice e scrivi test.
  4. Rimuovere le dipendenze indesiderate o utilizzare alternative.
  5. Utilizzare strumenti di sicurezza come audit npm per analizzare le tue dipendenze.

Se hai qualche idea sulla sicurezza di JavaScript, sentiti libero di condividerli nei commenti.