Photo by Jeswin Thomas on Unsplash
Quando inizi a programmare, va tutto alla grande. Scrivi e scrivi, segui nuovi corsi, guardi altre persone lavorare per migliorarti ed esplori di continuo nuovi framework, pattern, linguaggi, ecc.
Ma se hai un buon mentore o segui un corso più mirato, ti insegneranno una lezione importante: prima di cambiare linguaggio, avvicinarti ai pattern o esplorare i framework, dovresti conoscere le basi e i problemi comuni che incontrerai sviluppando le tue soluzioni. Ovviamente non puoi conoscere ogni problema o bug che può capitare mentre programmi. Ma, esplorando soluzioni, parlando con altri e usando gli strumenti giusti, puoi migliorare tantissimo.
La mia storia con la CWE-22 è iniziata alcuni anni fa, quando dovevo sviluppare un software Java per digitalizzare una clinica medica come parte del mio corso di ingegneria del software all'università.
Questo software doveva essere una semplice demo, perché lo scopo dell'esame era progettare correttamente il software e poi provare a implementarne una parte significativa usando i principi corretti. Quello che alcuni miei colleghi non avevano capito è che non tutti gli input sono da considerare affidabili.
Una delle funzionalità del software era la gestione dinamica di alcuni documenti. Potevi archiviarli tramite un'interfaccia comoda e recuperarli in seguito richiedendo il path che avevi scelto. E tutto qui: il diavolo si nascondeva nei dettagli!
Il bug, la vulnerabilità e l'escalation
Togliamo la maschera al bug e vediamo di cosa si tratta. Il path traversal è un problema comune quando qualcuno gestisce in modo poco ottimale i path relativi. Consiste nell'inserire un path usando i punti relativi per raggiungere un altro path nel filesystem. Se vuoi una definizione più formale, puoi consultare la pagina della OWASP Foundation a riguardo. Qui la terrò semplice.
Immagina di essere un utente chiamato user2 nel tuo sistema e di avere una struttura di directory come questa:
Struttura delle directory
Questa è una struttura di directory comune per una distribuzione Linux. Se sei un utente Windows, apparirà simile, tranne per il fatto che "/home/user2" diventerà qualcosa come "C:\Users\user2".
Eseguendo un comando di list otterrai i file presenti nella cartella.
Guardando la lista, noterai due file speciali, '.' e '..'. Indicano rispettivamente questa cartella e la cartella superiore. Quindi, se entri in ./test_files aprirai la cartella test_files, ma se entri in '..' ti sposterai nella cartella fuori dal progetto.
Questo significa che se un utente inserisce un path e quel path non viene controllato correttamente, può entrare in cartelle a cui non dovrebbe avere accesso, come 'etc', spostandosi di cartella in cartella fino alla sua destinazione proibita. Per esempio, dalla directory del progetto alla cartella etc, un utente dovrebbe attraversare ../../../../../../../etc.
Capiamolo meglio con un po' di codice.
In questo codice, gli utenti dovrebbero avere accesso solo alla cartella test_files, secondo lo sviluppatore, scrivendo il path corretto verso i file come in questa esecuzione.
Output
Ed è corretto. Il file contiene tre righe con un "1" per ciascuna riga.
Ma se l'utente ha più fantasia, può inserire l'input per attraversare il path fino al file passwd, per esempio.
Output dell'attraversamento
E il danno è fatto. Il '..' ha fatto sì che si attraversasse fino alla directory root prelevando il file passwd. Ci sono possibilità davvero spaventose riguardo a quello che un attaccante può fare con il file passwd, non trovi?
Metti in sicurezza con un fix
Per fortuna, questo bug può essere corretto semplicemente controllando dove sta andando l'utente. Se sai che l'utente dovrebbe muoversi solo "verso il basso di un certo path", perché dovresti lasciarlo risalire? La cosa più semplice da fare è verificare se il path inserito dall'utente è un path affidabile.
Puoi vedere che il fix è piuttosto semplice, ma diamogli un'occhiata più approfondita. La prima cosa che cambia è l'inizializzazione di un path affidabile che verrà usato in seguito per il nostro "controllo di sicurezza". Vogliamo "normalizzare" tutti i path forniti in input traducendo i path relativi in path assoluti. Fare questa traduzione ci permette di verificare se il path assoluto fornito ha la stessa parte iniziale del nostro path affidabile.
Il nostro path affidabile sarà qualcosa come /home/user2/Desktop/Projects/test/cwe-22/test_files. Quindi, una volta inserito il nostro path malevolo, verrà tradotto in /etc/passwd, che non ha nulla in comune con il nostro path affidabile tranne la '/' iniziale. Questo renderà vera la condizione del while, e il programma chiederà un path pulito.
Output dopo il fix
Ed ecco l'output del progetto dopo un'esecuzione. Come puoi vedere, il bug è corretto e la vulnerabilità non c'è più!
Correzione continua
La CWE-22 è piuttosto facile da correggere, ma che dire di qualcosa come la CWE-502, Deserialization of Untrusted Data. Potresti non aver mai sentito parlare di questa CWE e probabilmente non hai idea di quando e come possa colpirti. Qui entrano in gioco due ottimi strumenti gratuiti: GitHub e WhiteSource Cure.
Molti sviluppatori mettono il loro codice su GitHub, ma non tutti conoscono tutte le funzionalità di GitHub. Ha un sacco di workflow interessanti, come CI/CD e la gestione delle issue, che possono renderti la vita più facile.
Homepage di WhiteSource
WhiteSource Cure, d'altra parte, ti aiuta fornendo fix per i bug nel tuo repository GitHub. Come colleghi i due? Usi un file SARIF.
SARIF sta per Static Analysis Results Interchange Format. È un file che gli strumenti di analisi statica ti forniscono come output per comunicare il risultato della scansione con annessi metadati. Analizzatori statici molto diffusi che ti forniscono questo file SARIF sono PVS-Studio e detekt. Puoi anche usare uno strumento di sicurezza continua come LGTM. Una volta ottenuto il tuo file SARIF, ti basta aprire WhiteSource Cure e vedere i tuoi bug e come correggerli.
L'interfaccia è estremamente intuitiva. Inserisci l'URL del tuo repository e il file SARIF se non stai usando LGTM e clicca “Fix it!”.
Ma vediamo perché è così importante in un progetto un po' più grande. Se dai un'occhiata alla pagina LGTM di WhiteGoat, puoi vedere molti errori, inclusa la CWE-22.
CWE-22 sulla pagina LGTM di WebGoat
Questo è piuttosto utile quando sai effettivamente come correggere ogni bug. E, ovviamente, puoi passare un sacco di tempo a studiare per correggere ogni singolo bug e ogni CWE che affligge il tuo progetto. Ma, prima di decidere in tal senso, sposta la tua attenzione sulla stessa pagina del progetto su WhiteSource Cure.
La pagina mostra lo stesso bug relativo alla CWE-22, ma con una differenza importante: sul lato destro ti offrono un modo rapido per correggere il bug.
Pagina WebGoat di WhiteSource
I loro fix usano una loro libreria, CureKit, disponibile su GitHub sotto licenza Apache 2.0. Suona bene, vero?
Stai alla larga dalle insicurezze
Viviamo attualmente in un'era in cui la cybersecurity fa parte della nostra routine quotidiana. Ho visto molte storie di data leak, code leak, bug e tanti altri problemi sfruttati da attaccanti malintenzionati per il proprio tornaconto personale. Ma, se cresci ogni giorno imparando di più sulla cybersecurity e usando gli strumenti giusti per scoprire e correggere i tuoi bug, internet diventerà un posto più sicuro!