Rust, il nuovo linguaggio di programmazione a prova di errore che sta conquistando il tech

Rende alcune delle falle di sicurezza più comuni impossibili da introdurre, e nel settore si stanno moltiplicando i fan
coding
James Osborne/Pixabay

Che gestiate il reparto informatico di una grande azienda o siate semplici possessori di uno smartphone, conoscerete il flusso ininterrotto di aggiornamenti software che siamo costretti a installare per risolvere bug e problemi di sicurezza. Errare è umano, che il codice contenga errori è inevitabile, eccetera eccetera. Ma ultimamente si stanno moltiplicando le voci che chiedono di programmare i software in un linguaggio – chiamato Rust – che pare insolitamente a prova di errore. Per com’è concepito, gli sviluppatori che lo utilizzano non possono creare inavvertitamente le vulnerabilità più comuni, il che potrebbe rappresentare un’autentica svolta nel carosello quotidiano delle patch, e in ultima analisi nella cybersicurezza di tutto il mondo.

Anche i linguaggi di programmazione conoscono le loro mode, che il più delle volte vanno e vengono senza lasciare tracce indelebili. Nei suoi dodici anni di esistenza, Rust ha avuto il tempo di trasformarsi da progetto collaterale di un ricercatore di Mozilla in un solido ecosistema. Nel frattempo, il precedente linguaggio C, ancora oggi ampiamente utilizzato, ha da poco compiuto 50 anni. Ma poiché Rust produce codice più sicuro e – dettaglio fondamentale – nel farlo non intacca le prestazioni, questo linguaggio è andato accumulando sostenitori e si trova ora a un punto di svolta. Microsoft, Google e Amazon Web Services utilizzano Rust dal 2019, e nel 2020 le tre aziende, insieme a Mozilla e Huawei, si sono unite per costituire la Rust Foundation, un’organizzazione non profit che punta a promuovere e far crescere il linguaggio. Dopo un paio di anni di intenso lavoro, lo scorso ottobre il kernel Linux ha avviato i primi passi per implementare il supporto a Rust.

"Sta diventando un linguaggio virale – afferma Dave Kleidermacher, vicepresidente del settore tecnico per la sicurezza e la privacy di Android –. Stiamo investendo su Rust in Android e in tutta Google, e molti ingegneri cominciano a chiedersi: ‘Come faccio a iniziare anch’io? È fantastico’. Rust è appena diventato per la prima volta un linguaggio ufficialmente riconosciuto e accettato in Linux. E non è più limitato soltanto ad Android: oggi qualsiasi sistema basato su Linux può iniziare a incorporare componenti di Rust".

I vantaggi di Rust

Rust è un cosiddetto linguaggio "memory-safe", in quanto progettato per impedire ai programmi di estrarre accidentalmente dalla memoria di un computer dati non richiesti. Quando i programmatori usano linguaggi consolidati ma privi di questa caratteristica, comel C e il C++, devono regolare con cura i parametri dei dati che il loro programma si troverà a richiedere, e il modo in cui lo farà; un compito che a volte possono sbagliare anche gli sviluppatori più abili ed esperti. Programmando un nuovo software in Rust, invece, persino un dilettante può avere la certezza di non introdurre nel codice un bug di sicurezza della memoria.

La memoria di un programma è una risorsa condivisa utilizzata da tutte le sue funzionalità e librerie. Immaginiamo un programma per un calendario scritto in un linguaggio non sicuro per la memoria. Se apriamo il calendario e richiediamo le voci relative al 2 novembre 2022, il programma recupererà tutte le informazioni contenute nell'area della memoria del computer deputata a contenere i dati di quel giorno. Fin qui tutto normale. Ma se il programma non è stato progettato con i giusti vincoli, e se si richiedono le voci relative al 42 novembre 2022, il software – anziché produrre un errore o un’anomalia di altro tipo – potrebbe diligentemente restituire informazioni provenienti da una parte della memoria che ospita altri dati, per esempio la password usata per proteggere il calendario o il numero di carta di credito memorizzato per le sue funzionalità a pagamento. E se aggiungiamo al calendario una festa di compleanno indicando come data il 42 novembre, il sistema, anziché segnalare l'impossibilità di completare l'operazione, rischia di sovrascrivere nella memoria dati non correlati. Sono i cosiddetti bug di lettura e scrittura "out-of-bounds", ed è facile capire come possano essere sfruttati da intrusi per ottenere un accesso non autorizzato ai dati o addirittura il controllo esteso del sistema.

Un altra diffusa tipologia di bug di sicurezza della memoria, nota come "use-after-free", interessa le situazioni in cui un programma rinuncia a una porzione di memoria (mettiamo che abbiate cancellato tutte le voci di calendario relative al mese di ottobre 2022), ma conserva erroneamente l'accesso a essa. Se in seguito si richiedono i dati del 17 ottobre, il programma potrebbe riuscire a recuperare qualsiasi dato sia finito in quel settore. Se il codice contiene falle di sicurezza della memoria, un criminale informatico potrebbe per esempio creare un falso invito al calendario in una data o con dettagli dell'evento finalizzati a manipolare la memoria e fornire all’intruso l'accesso remoto.

Vulnerabilità di questo tipo non derivano da bug oscuri o secondari. Ricerche e verifiche hanno ripetutamente rilevato che costituiscono la maggior parte delle vulnerabilità. Anche programmando in Rust è possibile commettere errori e creare falle di sicurezza, ma la possibilità di eliminare le vulnerabilità della memoria è comunque significativa.

Ai problemi di sicurezza della memoria si deve una percentuale enorme delle vulnerabilità complessive rilevate, e questo in applicazioni fondamentali come sistemi operativi, telefoni cellulari e infrastrutture – osserva Dan Lorenc, amministratore delegato della società di sicurezza della catena di fornitura del software Chainguard –. Per decenni, mentre il codice veniva scritto in linguaggi non sicuri per la memoria, abbiamo cercato di migliorare e costruire strumenti più efficaci, e di insegnare alle persone a non commettere certi errori, ma spiegare che bisogna impegnarsi funziona fino a un certo punto. Ecco perché serve una tecnologia nuova che renda semplicemente impossibile un’intera categoria di vulnerabilità. Ed è esattamente quello che offre Rust".

Critici e ostacoli

Rust non è privo di scettici e detrattori. Negli ultimi due anni, il tentativo di implementarlo in Linux è stato accompagnato da polemiche, un po’ perché integrare il supporto per qualsiasi altro linguaggio aumenta fisiologicamente le difficoltà, e un po’ per i diversi pareri su come far funzionare il tutto nel dettaglio. I suoi sostenitori, però, sottolineano che Rust ha le carte in regola – non causa cali di prestazioni e interagisce bene con i software programmati in altri linguaggi – e che a renderlo indispensabile è il semplice fatto che risponde a un'esigenza impellente.

"Più che essere la scelta giusta, è quella già a disposizione – spiega Lorenc, esperto ricercatore e collaboratore open-source –. Al momento non esistono vere alternative, se non restare inerti, e quello non è più possibile. Continuare per altri dieci anni a usare codice pericoloso per la memoria comporterebbe enormi problemi per per il settore tecnologico, per la sicurezza nazionale, per qualsiasi cosa".

Tra i maggiori ostacoli alla transizione a Rust, tuttavia, ci sono proprio i vari decenni in cui gli sviluppatori hanno scritto codice fondamentale in linguaggi non sicuri per la memoria. Programmare nuovi software in Rust non risolve questo enorme accumulo di arretrati. L'implementazione nel kernel di Linux, per esempio, è cominciata dalla periferia, con il supporto ai driver basati su Rust, i programmi che coordinano il sistema operativo con componenti hardware come le stampanti.

"Quando si tratta di sistemi operativi, la velocità e le prestazioni sono sempre al primo posto, e in genere le parti che si eseguono in C++ o in C sono quelle che non si possono eseguire in Java o in altri linguaggi sicuri per la memoria, per non intaccare le prestazioni – sottolinea Kleidermacher di Google –. Per questo poter usare Rust e ottenere le stesse prestazioni mantenendo al sicuro la memoria è una gran bella cosa. Ma la strada è lunga. Non si possono riscrivere 50 milioni di righe di codice da un giorno all'altro, ragion per cui stiamo individuando con attenzione i componenti più rilevanti per la sicurezza, e piano piano andremo adeguando il resto".

Per quanto riguarda Android, afferma Kleidermacher, molte funzioni di gestione delle chiavi di crittografia vengono ormai scritte in Rust, così come la funzione di comunicazione privata su Internet Dns su Https, una nuova versione dello stack di chip a banda ultralarga, e il nuovo Android Virtualization Framework utilizzato nei chip Tensor G2 di Google. Il team Android, aggiunge Kleidermacher, sta convertendo a Rust stack di connettività come quelli per il Bluetooth e il Wi-Fi a un ritmo crescente, perché si basano su standard industriali complessi e sono soliti contenere molte falle. La strategia, insomma, consiste nel cominciare a migliorare la sicurezza per gradi, convertendo a Rust prima i componenti software più esposti o cruciali, per poi procedere a ritroso verso l’interno.

"Sì, è un lavoro enorme e richiederà molto tempo, ma di quanti trilioni di dollari e programmatori di talento dispone l'industria tecnologica? Le risorse non mancano – dice Josh Aas, direttore esecutivo dell'Internet Security research group, che dirige il progetto Prossimo, dedicato alla sicurezza della memoria, e l'autorità di certificazione gratuita Let's encrypt –. E i problemi che richiedono solo molto lavoro sono i migliori".

Mentre Rust si avvia verso un’adozione sempre più diffusa, la necessità di risolvere i problemi di sicurezza della memoria viene ribadita quotidianamente da più parti. “Quante persone, in questo momento, vivono l'incubo del furto d'identità a causa di un bug relativo alla memoria? O pensando alla sicurezza nazionale: se a farci paura sono gli attacchi informatici agli Stati Uniti, in che misura possono dipendere da falle di sicurezza della memoria? – si domanda Aas –. Per come la vedo io, ormai si tratta solo di convincere la gente. Ci è sufficientemente chiara la natura del rischio? E soprattutto: c’è la volontà di farlo?”.

Questo articolo è apparso originariamente su Wired Us ed è stato adattato da Matteo Colombo.