Immagine in evidenza di Mikhail Fesenko da Unsplash
Negli ultimi anni, la software supply chain è diventata sempre più una componente critica del processo di sviluppo, un ruolo che la rende particolarmente fragile dal punto di vista della cybersecurity. Con l’aumento dell’interconnessione tra servizi, l’adozione massiva di soluzioni cloud native e una dipendenza sempre maggiore da software open source, ogni progetto software si trova a fare affidamento su un numero crescente di componenti di terze parti. Questi componenti offrono allo sviluppatore flessibilità e velocità di sviluppo, ma amplificano la superficie d’attacco, trasformando questa catena di dipendenze in un bersaglio particolarmente ambito per gli attaccanti.
Negli ultimi anni alcuni episodi paradigmatici hanno spinto l’industria e persino i governi a rivalutare le proprie strategie di cybersecurity.
Cos’è la Software Supply Chain?
Per software supply chain intendiamo tutti gli strumenti di terze parti che usiamo per sviluppare, testare e distribuire software. In questa ampia definizione troviamo le dipendenze di terze parti – oggi soprattutto librerie e framework open source, ma anche componenti e servizi – che vengono aggiunte al codice del progetto, e anche le dipendenze transitive, ovvero le dipendenze di queste dipendenze, e così via. Con la presentazione di Docker nel 2013, che ha dato idealmente il via all’era cloud native, la supply chain è diventata sempre più complessa e articolata: oggi il ciclo di vita di un software è strettamente legato alla presenza di un repository per il codice (ovvero dove esso risiede), una CI/CD (Continuous Integration / Continuous Delivery, sistemi automatici per assemblare, testare e distribuire un software) e un deployment (rilascio) in cloud, e ogni pezzo di questo puzzle rappresenta un anello in più nella catena, un anello potenzialmente debole e quindi sfruttabile per un attacco.
Per fare un paragone, possiamo immaginare la software supply chain come una catena di montaggio in cui ogni pezzo, anche uno apparentemente secondario, è fondamentale per il prodotto finale. Se un singolo componente è vulnerabile o viene compromesso da un attacco, l’intero sistema può risentirne, esponendo le applicazioni e i dati sensibili a gravi rischi. Non solo, anche il trasporto ovvero la distribuzione dei componenti è soggetto a vulnerabilità, così come il processo di assemblaggio (la cosiddetta build) e quello della distribuzione agli utenti finali.
Minacce nella Supply Chain – SLSA Specification (https://slsa.dev/spec/v1.0/threats-overview)
La complessità e i rischi della Software Supply Chain
Secondo una ricerca del 2019 (Small World with High Risks: A Study of Security Threats in the npm Ecosystem), installare un pacchetto da npm, ovvero il principale repository di progetti JavaScript, linguaggio di programmazione tra i più utilizzati al mondo, introduce in media una fiducia implicita su 79 software di terze parti e 39 maintainer.
npm è una piattaforma con numeri impressionanti: più di 2,5 milioni di pacchetti ospitati, 37 milioni di versioni totali di questi pacchetti, e un volume di richieste annuali pari a 2,6 trilioni (fonte: Sonatype). Ma anche gli altri ecosistemi sono giganteschi: Maven (Java) ospita 557 mila progetti, PyPI (Python) 475 mila, NuGet (.NET) 367 mila (tutti i dati sono aggiornati al 2023), e tutti questi pacchetti finiscono potenzialmente nelle dipendenze dirette o indirette di software che utilizziamo tutti i giorni, dai siti web ai browser fino ai sistemi operativi.
In questo contesto, un attaccante non ha bisogno di colpire direttamente il codice dell’applicazione: è sufficiente sfruttare una vulnerabilità all’interno di una dipendenza, una configurazione errata nel processo di CI/CD, o persino un errore nel processo di build o di distribuzione. Attacchi come questi sono diventati sempre più frequenti, portando a incidenti di grande portata e dimostrando come una compromissione mirata possa avere effetti devastanti su tutta la filiera, con costi elevatissimi per la società.
Gli analisti di Snyk stimano che il costo totale degli attacchi alla supply chain raggiungerà i 138 miliardi di dollari entro il 2031.
Il caso SolarWinds
Uno degli esempi più emblematici è stato il caso SolarWinds. SolarWinds è una società americana specializzata in software di gestione per infrastrutture IT, usato per monitorare e ottimizzare reti e sistemi informatici di aziende e agenzie governative, e uno dei suoi prodotti principali si chiama Orion. Nel 2020, un gruppo noto come APT29, o Cozy Bear, riuscì a compromettere il ciclo di build di Orion, iniettando un malware all’interno di uno degli aggiornamenti che venivano distribuiti ai clienti automaticamente. Questo attacco, noto come SUNBURST dal nome dato al malware stesso, fu uno dei più devastanti mai registrati, sia per gli alti privilegi con cui Orion viene eseguito essendo un tool di monitoraggio che richiede accesso a dati e configurazioni sensibili, sia per l’importanza strategica delle aziende colpite: SolarWinds ha infatti tra i suoi clienti agenzie governative, istituzioni finanziarie e grandi aziende tecnologiche, soprattutto negli Stati Uniti.
La vulnerabilità Log4Shell
L’anno successivo, nel 2021, un altro caso ebbe grande risalto e riguardò Log4j, una libreria per la generazione di log e una delle dipendenze più diffuse nell’ecosistema Java. La scoperta della vulnerabilità chiamata Log4Shell (che permette l’esecuzione di codice remoto) ha scatenato una corsa globale per aggiornare milioni di server, mostrando come la presenza di una falla in una libreria così diffusa possa avere ripercussioni su una scala enorme. Anche gli incidenti riguardanti pacchetti più piccoli, come quelli che hanno coinvolto le librerie colors e faker in JavaScript, hanno mostrato che attaccanti, malintenzionati, o persino i maintainer stessi possono compromettere software largamente utilizzati, con conseguenze imprevedibili.
Il rischio sventato con PostgreSQL
E non stiamo parlando di un altro caso devastante solamente per una questione di fortuna: all’inizio di quest’anno, durante una normale analisi delle performance di PostgreSQL, uno dei sistemi di gestione database più noti e consolidati, l’ingegnere Microsoft Andres Freund ha notato un comportamento anomalo nell’utilizzo della CPU durante le operazioni di decompressione. Indagando più a fondo, ha scoperto che nella libreria XZ era stato inserito del codice malevolo che avrebbe potuto permettere l’esecuzione di codice arbitrario su innumerevoli sistemi Linux che la utilizzano.
Se una vulnerabilità così grave è stata scoperta quasi per caso, è ragionevole supporre che molte altre potrebbero essere ancora nascoste nel software che usiamo ogni giorno. Una considerazione che mette in luce l’intrinseca fragilità della nostra supply chain.
Le proposte di regolamentazione dagli Usa all’Ue
Proprio per questo, i governi di tutto il mondo hanno rivolto grandi attenzioni alla cybersecurity, evidenziando l’importanza di una regolamentazione specifica per la software supply chain. Negli Stati Uniti, l’amministrazione Biden ha risposto con l’Executive Order on Improving the Nation’s Cybersecurity, emanato nel 2021, che prevede misure concrete per rafforzare la sicurezza informatica a livello federale e richiede ai fornitori di software di seguire standard di sicurezza più rigorosi, come quelli che vedremo a breve.
Anche l’Unione Europea si è mossa con iniziative legislative, come il Cyber Resilience Act (approvato definitivamente nel 2024) e la Direttiva NIS2 (2023). Il Cyber Resilience Act mira a stabilire requisiti di sicurezza per i prodotti con componenti digitali, ad esempio l’assenza di vulnerabilità note prima dell’immissione sul mercato, mentre la Direttiva NIS2 impone agli Stati membri di innalzare i livelli di sicurezza in settori critici, tra cui la tecnologia e le infrastrutture digitali.
Queste leggi incoraggiano l’adozione di pratiche di sicurezza avanzate lungo tutta la supply chain, e mettono in evidenza quanto il tema sia considerato critico per la sicurezza di istituzioni e cittadini.
Soluzioni e contromisure che l’industria sta adottando
Prima di analizzare le contromisure, è importante comprendere cosa si intende per vulnerabilità di un software. Una vulnerabilità è una debolezza nel codice o nella configurazione che può essere sfruttata per compromettere la sicurezza del sistema. Queste vulnerabilità quando scoperte vengono catalogate nel formato standard CVE (Common Vulnerabilities and Exposures) in registri pubblici che vi assegnano un identificativo univoco (CVE ID) e un indicatore di gravità (CVSS), permettendo così a sviluppatori e organizzazioni di tracciare e gestire i rischi in modo standardizzato. Tra i database più importanti citiamo il National Vulnerability Database del NIST e OSV.dev.
Ma oltre alle vulnerabilità, che sono nella maggior parte dei casi accidentali, dobbiamo considerare anche gli attacchi intenzionali all’integrità del software, ovvero dobbiamo avere la garanzia che il codice non sia stato alterato dal momento della sua scrittura fino alla sua distribuzione. Un software è considerato integro solo quando possiamo verificare che ogni componente provenga da una fonte fidata e non sia stato manipolato durante il suo “viaggio” attraverso la supply chain.
OSV.dev homepage (https://osv.dev/)
Il primo passo dunque è il monitoraggio costante delle dipendenze per identificare vulnerabilità note. Strumenti automatici come Dependabot di GitHub e Renovate di Mend svolgono un ruolo cruciale in questo processo: analizzano continuamente le dipendenze dei progetti software, confrontandole con i database di CVE e avvisando gli sviluppatori quando viene scoperta una debolezza in una delle componenti utilizzate. Questi tool non si limitano a segnalare il problema, ma creano automaticamente delle “pull request”, ovvero una modifica pronta per essere integrata nel codice sorgente dell’applicazione monitorata, per aggiornare le dipendenze vulnerabili alle versioni sicure, semplificando notevolmente il processo di manutenzione.
Ma questo non è sufficiente: dobbiamo anche assicurarci che il software che stiamo utilizzando sia effettivamente quello che pensiamo di utilizzare, e che non sia stato manomesso durante il suo percorso dalla sorgente alla distribuzione. È qui che entrano in gioco framework come SLSA (Supply-chain Levels for Software Artifacts), nato in Google e successivamente donato a OpenSSF (Open Source Security Foundation). SLSA definisce quattro livelli incrementali di sicurezza della supply chain, partendo dalla tracciabilità del processo di build (livello 1) fino ad arrivare a garantire l’immutabilità e la ripetibilità delle build con controlli di accesso rigorosi e certificati di provenienza firmati da infrastrutture fidate (livello 4). Complementare a SLSA è il concetto di SBOM (Software Bill of Materials), un documento che elenca in modo dettagliato tutte le componenti software utilizzate in un progetto, incluse le dipendenze transitive. Gli SBOM stanno rapidamente diventando uno standard de facto, tanto che nel 2021 un ordine esecutivo del governo degli Stati Uniti ne ha reso obbligatorio l’utilizzo per i fornitori di software delle agenzie federali.
Per tornare all’analogia con il mondo industriale che abbiamo citato all’inizio dell’articolo, possiamo pensare a SLSA come a un sistema di certificazione che assicura che tutta la catena di montaggio sia stata ispezionata e validata, mentre SBOM funziona come una distinta dei materiali usati nel processo di produzione. In questo modo possiamo garantire che ogni componente sia privo di difetti noti, provenga da fonti affidabili, e non sia stato alterato durante il processo di approvvigionamento.
I citati SLSA, SBOM e i tool automatici come Dependabot e Renovate sono solamente alcuni dei risultati concreti che l’industria ha raggiunto in questi anni. Un discorso a parte meriterebbe il ruolo delle grandi aziende, come le citate Google e GitHub (quindi Microsoft), le fondazioni come Linux Foundation e OpenSSF (che ne è una costola), e la comunità di sviluppatori open source. Raggiungere l’agognata “resilienza” è un obiettivo ambizioso che richiede la partecipazione attiva di sviluppatori, aziende, governi e comunità. La speranza è che, con tecnologie e standard sempre migliori e una consapevolezza crescente, si possa davvero raggiungerlo.