Bug JavaScript in abbondanza nell'ecosistema Node.js: rilevati automaticamente in PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

JavaScript in abbondanza nell'ecosistema Node.js – trovato automaticamente

Ecco un interessante documento della recente conferenza USENIX del 2022: Mining delle vulnerabilità di Node.js tramite il grafico e la query delle dipendenze dagli oggetti.

Qui imbrogliamo un po' evitando di approfondire e spiegare la ricerca principale presentata dagli autori dell'articolo (un po' di matematica e la conoscenza della notazione semantica operativa è auspicabile durante la lettura), che è un metodo per il metodo statico analisi del codice sorgente che chiamano ODGEN, abbreviazione di Generatore di grafici di dipendenza dagli oggetti.

Invece, vogliamo concentrarci sulle implicazioni di ciò che sono stati in grado di scoprire nell'ecosistema JavaScript Node Package Manager (NPM), in gran parte automaticamente, utilizzando i loro strumenti ODGEN nella vita reale.

Un fatto importante qui è, come accennato in precedenza, che i loro strumenti sono destinati a ciò che è noto come analisi statica.

È qui che miri a rivedere il codice sorgente per probabili (o effettivi) errori di codifica e falle di sicurezza senza eseguirlo affatto.

Testarlo in esecuzione è un processo molto più dispendioso in termini di tempo, che generalmente richiede più tempo per l'impostazione e più tempo per l'esecuzione.

Come potete immaginare, però, i cosiddetti analisi dinamica – costruire effettivamente il software in modo da poterlo eseguire ed esporlo a dati reali in modi controllati – generalmente dà risultati molto più approfonditi ed è molto più probabile che esponga bug arcani e pericolosi rispetto al semplice “guardarlo attentamente e intuire come funziona” ”.

Ma l'analisi dinamica non solo richiede tempo, ma è anche difficile da fare bene.

Con questo, intendiamo davvero dire che il test dinamico del software lo è molto facile fare male, anche se dedichi molto tempo a questo compito, perché è facile ritrovarsi con un numero impressionante di test che tuttavia non sono così vari come pensavi e che il tuo software quasi sicuramente supererà, qualunque cosa accada. I test dinamici del software a volte finiscono come un insegnante che pone le stesse domande d'esame anno dopo anno, in modo che gli studenti che si sono concentrati interamente sulla pratica dei "documenti precedenti" finiscono per fare altrettanto bene degli studenti che hanno veramente padroneggiato l'argomento.

Una rete disordinata di dipendenze della catena di approvvigionamento

Negli enormi ecosistemi di codice sorgente del software di oggi, di cui i repository open source globali come NPM, PyPI, PHP Packagist e RubyGems sono esempi ben noti, molti prodotti software si basano su vaste raccolte di pacchetti di altre persone, formando una rete di approvvigionamento complessa e discontinua dipendenze a catena.

Implicita in queste dipendenze, come puoi immaginare, è una dipendenza da ciascuna suite di test dinamici fornita da ciascun pacchetto sottostante – e quei test individuali generalmente non (anzi, non possono) tenere conto di come interagiranno tutti i pacchetti quando sono combinati per formare la tua applicazione unica.

Quindi, sebbene l'analisi statica di per sé non sia davvero adeguata, è comunque un ottimo punto di partenza per la scansione di repository software alla ricerca di buchi evidenti, anche perché l'analisi statica può essere eseguita "offline".

In particolare, puoi scansionare regolarmente e regolarmente tutti i pacchetti di codice sorgente che usi, senza bisogno di costruirli in programmi in esecuzione e senza dover inventare script di test credibili che costringano quei programmi a essere eseguiti in una varietà realistica di modi.

Puoi persino scansionare interi repository di software, inclusi i pacchetti che potresti non aver mai bisogno di usare, per eliminare il codice (o per identificare gli autori) di cui non ti fidi del software prima ancora di provarlo.

Meglio ancora, alcuni tipi di analisi statica possono essere utilizzati per esaminare tutto il software alla ricerca di bug causati da errori di programmazione simili che hai appena trovato tramite l'analisi dinamica (o che sono stati segnalati tramite un sistema di bug bounty) in una singola parte di un singolo software Prodotto.

Ad esempio, immagina una segnalazione di bug del mondo reale che è arrivata dall'ambiente in base a un punto specifico nel tuo codice in cui hai usato uno stile di codifica che ha causato un uso-dopo-libero errore di memoria.

A uso-dopo-libero è dove sei certo di aver finito con un certo blocco di memoria e restituiscilo in modo che possa essere utilizzato altrove, ma poi dimentica che non è più tuo e continua a usarlo comunque. Come tornare accidentalmente a casa dal lavoro al tuo vecchio indirizzo mesi dopo che te ne sei andato, solo per abitudine, e chiedendoti perché c'è una strana macchina nel vialetto.

Se qualcuno ha copiato e incollato quel codice difettoso in altri componenti software nel repository della tua azienda, potresti riuscire a trovarli con una ricerca di testo, presupponendo che la struttura complessiva del codice sia stata mantenuta e che i commenti e i nomi delle variabili non siano stati non è cambiato molto.

Ma se altri programmatori si limitassero a seguire lo stesso linguaggio di codifica, magari addirittura riscrivendo il codice difettoso in un linguaggio di programmazione diverso (in gergo, in modo che fosse lessicalmente diverso) ...

...quindi la ricerca di testo sarebbe quasi inutile.

Non sarebbe comodo?

Non sarebbe utile se potessi cercare staticamente nell'intera base di codice gli errori di programmazione esistenti, basandosi non su stringhe di testo ma invece su caratteristiche funzionali come il flusso di codice e le dipendenze dai dati?

Ebbene, nel documento USENIX di cui stiamo discutendo qui, gli autori hanno tentato di costruire uno strumento di analisi statica che combina una serie di diverse caratteristiche del codice in una rappresentazione compatta che denota "come il codice trasforma i suoi input nei suoi output e quali altre parti del codice arrivano ad influenzare i risultati”.

Il processo si basa sui suddetti grafici di dipendenza dagli oggetti.

Estremamente semplificata, l'idea è quella di etichettare il codice sorgente in modo statico in modo da poter dire quali combinazioni di codice e dati (oggetti) in uso in un punto possono influenzare gli oggetti che verranno utilizzati in seguito.

Quindi, dovrebbe essere possibile cercare comportamenti di codice dannosi noti – odori, in gergo, senza la necessità di testare il software dal vivo e senza dover fare affidamento solo sulla corrispondenza del testo nell'origine.

In altre parole, potresti essere in grado di rilevare se il programmatore A ha prodotto un bug simile a quello appena trovato dal programmatore B, indipendentemente dal fatto che A abbia letteralmente copiato il codice di B, seguito i consigli errati di B o semplicemente adottato le stesse cattive abitudini sul posto di lavoro. come B.

In parole povere, una buona analisi statica del codice, nonostante non guardi mai il software in esecuzione nella vita reale, può aiutare a identificare una programmazione scadente fin dall'inizio, prima di iniettare nel tuo progetto bug che potrebbero essere sottili (o rari) abbastanza nella vita reale da non presentarsi mai, anche sotto test dal vivo approfonditi e rigorosi.

E questa è la storia che abbiamo deciso di raccontarvi all'inizio.

300,000 pacchi elaborati

Gli autori del documento hanno applicato il loro sistema ODGEN a 300,000 pacchetti JavaScript dal repository NPM per filtrare quelli che il loro sistema ha suggerito potrebbero contenere vulnerabilità.

Di questi, hanno mantenuto i pacchetti con più di 1000 download settimanali (sembra che non avessero il tempo di elaborare tutti i risultati) e hanno determinato con un ulteriore esame quei pacchetti in cui pensavano di aver scoperto un bug sfruttabile.

In questi, hanno scoperto 180 bug di sicurezza dannosi, tra cui 80 vulnerabilità di iniezione di comandi (è qui che i dati non attendibili possono essere passati ai comandi di sistema per ottenere risultati indesiderati, in genere inclusa l'esecuzione di codice in modalità remota) e 14 ulteriori bug di esecuzione di codice.

Di questi, a 27 sono stati infine assegnati numeri CVE, riconoscendoli come falle di sicurezza "ufficiali".

Sfortunatamente, tutti quei CVE sono datati 2019 e 2020, perché la parte pratica del lavoro in questo documento è stata fatta più di due anni fa, ma è stata scritta solo ora.

Tuttavia, anche se lavori in un ambiente meno raffinato di quanto sembrano fare gli accademici (per la maggior parte degli operatori di sicurezza informatica attivi, combattere i criminali informatici di oggi significa terminare qualsiasi ricerca effettuata il prima possibile in modo da poterla utilizzare subito)...

…se stai cercando argomenti di ricerca che possano aiutarti a contrastare gli attacchi alla catena di fornitura negli odierni repository software su scala gigante, non trascurare l’analisi statica del codice.

La vita nel vecchio cane ancora

L'analisi statica è caduta in disgrazia negli ultimi anni, anche perché i popolari linguaggi dinamici come JavaScript rendono frustrante l'elaborazione statica.

Ad esempio, una variabile JavaScript potrebbe essere un numero intero in un momento, quindi avere una stringa di testo "aggiunta" ad essa in modo perfettamente legale anche se in modo errato, trasformandola così in una stringa di testo e in seguito potrebbe finire come un altro tipo di oggetto del tutto.

Inoltre, una stringa di testo generata dinamicamente può magicamente trasformarsi in un nuovo programma JavaScript, compilato ed eseguito in fase di runtime, introducendo così comportamenti (e bug) che non esistevano nemmeno al momento dell'analisi statica.

Ma questo documento suggerisce che, anche per i linguaggi dinamici, un'analisi statica regolare dei repository su cui fai affidamento può comunque aiutarti enormemente.

Gli strumenti statici non solo possono trovare bug latenti nel codice che stai già utilizzando, anche in JavaScript, ma ti aiutano anche a giudicare la qualità di fondo del codice in qualsiasi pacchetto che stai pensando di adottare.


SCOPRI DI PIÙ SULLA PREVENZIONE DEGLI ATTACCHI ALLA CATENA DI FORNITURA

Questo podcast presenta l'esperto Sophos Chester Wisniewski, Principal Research Scientist di Sophos, ed è pieno di consigli utili e attuabili sulla gestione degli attacchi alla catena di approvvigionamento, sulla base delle lezioni che possiamo imparare dagli attacchi giganti del passato, come Kaseya e SolarWinds.

Se non viene visualizzato alcun lettore audio sopra, ascolta direttamente su Soundcloud.
Puoi anche leggere l'intero podcast come a Trascrizione completa.


Timestamp:

Di più da Sicurezza nuda