Viene pubblicata una vulnerabilità critica, l'advisory si diffonde e nel giro di un'ora qualcuno chiede nella chat aziendale: siamo coinvolti? Log4Shell ha reso famosa la domanda. CVE-2021-44228 colpiva Log4j Core dalla 2.0-beta9 fino alla 2.15.0, una libreria che si trovava diversi livelli in profondità nell'albero delle dipendenze di innumerevoli prodotti Java, e la maggior parte dei team ha dovuto scoprire a proprie spese dove fosse.

La domanda sembra semplice. In realtà sono tre domande:

  1. Il componente vulnerabile è in qualcosa che compiliamo o distribuiamo?
  2. Se c'è, può essere sfruttato nel nostro prodotto?
  3. Da quando, e in quali release?

La maggior parte dei processi risponde alle prime due. La terza è quella che clienti, auditor e autorità di regolamentazione pongono subito dopo, ed è quella a cui è più difficile rispondere a posteriori.

Fase 1: scoprire se il componente è presente

Di solito le aziende arrivano a una risposta in uno di quattro modi, grosso modo in ordine di maturità.

Chiedere in giro e cercare. Qualcuno scrive su Slack, gli ingegneri cercano il nome del pacchetto nei repository e nei lockfile, e un foglio di calcolo raccoglie le risposte. È ancora il metodo più comune. È lento, dipende da chi risponde e non vede nulla che non sia dichiarato in un file: dipendenze delle dipendenze, librerie vendorizzate, immagini base, strumenti installati durante la build.

Controllare le dashboard degli scanner. Gli scanner delle dipendenze segnalano la CVE per repository nel giro di poche ore. È più veloce, ma uno scanner riferisce sul codice che ha davanti oggi, di solito il branch predefinito. Non Le dice quali release usano i Suoi clienti, né che cosa ha effettivamente scaricato una build di tre mesi fa.

Interrogare un inventario di SBOM. I team che conservano una software bill of materials per ogni release possono porre una sola domanda su tutte: quali prodotti e versioni contengono le versioni interessate di questo pacchetto? È il primo metodo che risponde per il software che ha distribuito, non solo per il software nel repository.

Confrontare di continuo. Quando le SBOM sono monitorate rispetto ai dati sulle vulnerabilità, l'elenco dei prodotti colpiti esiste prima che qualcuno lo chieda. La conversazione in chat inizia con la risposta invece che con la domanda.

La qualità di ogni metodo dipende da ciò che l'inventario contiene davvero. I punti ciechi abituali sono:

  • Dipendenze transitive. Il pacchetto vulnerabile raramente è uno che ha aggiunto Lei. Arriva tre o quattro livelli più in basso.
  • Tutto ciò che il manifest non dichiara. Pacchetti installati da script di build, strumenti npx, passaggi di Dockerfile, cache ripristinate e codice C e C++ vendorizzato.
  • Vecchie release. Un branch che non compila più non può essere riscansionato, ma il prodotto compilato da quel branch può essere ancora in uso sul campo.

Fase 2: decidere se conta

Un componente può essere presente senza costituire un rischio reale, quindi il passo successivo è il triage:

  • Versione e configurazione. La versione rientra esattamente nell'intervallo interessato? La funzionalità vulnerabile è compilata e attiva?
  • Raggiungibilità. Il Suo codice chiama davvero la funzione vulnerabile?
  • Esposizione. Il componente è raggiungibile dalla rete o da input non attendibili, oppure è usato solo in fase di build?
  • Mitigazioni. Esiste un sandboxing, una restrizione di rete o una configurazione che blocca l'exploit?
  • Segnali di sfruttamento. CVSS indica la gravità, EPSS stima la probabilità che una CVE venga sfruttata nei prossimi 30 giorni e il Known Exploited Vulnerabilities catalog della CISA elenca quelle già sfruttate in the wild. Insieme decidono che cosa esaminare per primo.

Fase 3: registrare la decisione

L'esito viene registrato per prodotto e versione, sempre più spesso come dichiarazione VEX (Vulnerability Exploitability eXchange). I requisiti minimi per il VEX della CISA definiscono quattro stati: not affected, affected, fixed e under investigation. Una dichiarazione "not affected" deve spiegare il motivo, per esempio perché il codice vulnerabile non è presente o non è raggiungibile da un attaccante.

Quel registro alimenta tutto ciò che segue: la correzione e le release che la contengono, l'advisory di sicurezza per i clienti e qualsiasi segnalazione attesa da un'autorità di regolamentazione. Con il Cyber Resilience Act dell'UE, per esempio, un fabbricante deve inviare un preallarme su una vulnerabilità attivamente sfruttata nel proprio prodotto entro 24 ore da quando ne viene a conoscenza.

Fase 4: calcolare la finestra di esposizione

"Siamo coinvolti?" ha una seconda metà che spesso viene saltata: per quanto tempo lo siamo stati?

La vulnerabilità esisteva molto prima della pubblicazione della CVE. Log4Shell era in Log4j dalla 2.0-beta9, rilasciata anni prima che qualcuno la divulgasse. La Sua esposizione è iniziata il giorno in cui una build ha scaricato per la prima volta una versione vulnerabile ed è terminata il giorno in cui l'ultima build che la conteneva è stata sostituita. Questa finestra Le serve per:

  • dire ai clienti quali delle release che usano sono colpite, non solo l'ultima
  • limitare un'indagine sull'incidente al periodo giusto, se la vulnerabilità può essere stata sfruttata
  • mostrare a un auditor o a un'autorità di regolamentazione quando il problema è entrato nel prodotto e quando è stata distribuita la correzione

Scansionare il codice di oggi non può darLe tutto questo. Il lockfile attuale dice che cosa vuole il repository adesso, non che cosa ha installato ogni build passata. L'unica fonte affidabile è un registro di ogni build, acquisito durante l'esecuzione e conservato in seguito.

Come risponde CRACI

CRACI esegue i Suoi job GitHub Actions sui propri runner e registra ogni pacchetto che ciascuna build scarica effettivamente, diretto e transitivo, compresi i pacchetti installati da script e ripristinati dalle cache. La SBOM di ogni build viene conservata, quindi la cronologia è già lì quando viene pubblicata una CVE.

Quando arriva una nuova CVE, la risposta è già pronta: ogni build passata e la sua SBOM, quali di esse contenevano la dipendenza vulnerabile, diretta o transitiva, e il periodo in cui Lei è stato colpito. Niente fogli di calcolo, niente nuove scansioni, niente ricostruzioni dai lockfile. La prima build che la conteneva e la build che l'ha rimossa Le danno la finestra di esposizione, fin dove arriva la Sua retention (180 giorni per impostazione predefinita, retention personalizzata su Enterprise).

Una volta saputo, un policy gate può bloccare le build che contengono questa CVE, così un successivo aggiornamento delle dipendenze o una cache ripristinata non possono riportare di nascosto la versione vulnerabile in una release.

Da lì il resto del processo ha una base su cui poggiare:

  • CRACI monitora le SBOM di continuo, quindi le nuove CVE vengono confrontate con le Sue build senza che nessuno lo chieda.
  • I team di sicurezza effettuano il triage delle vulnerabilità rilevate e le inviano ai team responsabili della correzione, e CRACI supporta il VEX per registrare l'esito.
  • L'inventario di CRACI mostra quali versioni del software sono distribuite su quali prodotti.
  • Per il CRA, CRACI invia per Suo conto il preallarme, la notifica e la relazione finale.

Prenoti una demo per vedere la cronologia delle build di uno dei Suoi repository.