Creare una SBOM: la distinta base del software per il Cyber Resilience Act

Zwei Entwickler und eine Entwicklerin werten gemeinsam Daten auf mehreren Bildschirmen aus

Qualità e sicurezza

Alla fine del 2021 divenne nota la vulnerabilità Log4Shell nella diffusissima libreria Java Log4j. In molte aziende iniziò allora una ricerca durata giorni: la libreria è contenuta in uno dei nostri prodotti – e se sì, in quale versione? Chi aveva una distinta base del software rispose alla domanda in pochi minuti. Con il Cyber Resilience Act questa distinta base diventa un obbligo per i fabbricanti.

Che cosa deve contenere una SBOM

Il CRA definisce la distinta base del software, in inglese Software Bill of Materials (SBOM), come registrazione formale dei dettagli e delle relazioni nella catena di fornitura dei componenti contenuti nel software di un prodotto. In pratica è un elenco leggibile meccanicamente di tutte le librerie, i pacchetti e i moduli. Per ogni componente ne fanno parte almeno:

  • nome e versione,
  • produttore o fornitore,
  • un identificativo univoco, per lo più come Package URL, ad esempio pkg:nuget/Newtonsoft.Json@13.0.3,
  • un checksum del file distribuito,
  • la licenza,
  • le dipendenze da altri componenti.

Ciò che non vi rientra sono le vulnerabilità. Se una falla riguarda effettivamente il Suo prodotto lo registra separatamente, ad esempio in un documento VEX (Vulnerability Exploitability eXchange).

Che cosa richiede il CRA – e che cosa no

L'allegato I, parte II, punto 1 richiede una SBOM in un formato comune leggibile meccanicamente, dalla quale risultino almeno le dipendenze di primo livello. Fa parte della documentazione tecnica e va consegnata all'autorità di vigilanza del mercato su richiesta motivata. Non è obbligatorio pubblicarla. Se la mette a disposizione dei Suoi clienti, indichi nelle informazioni per gli utenti dove si trova. Un formato fisso il regolamento finora non lo prescrive; la Commissione può stabilirlo mediante un atto di esecuzione.

Un buon riferimento lo fornisce già oggi la direttiva tecnica TR-03183-2 del BSI. La versione 2.1.0 richiede JSON o XML nel formato CycloneDX a partire dalla versione 1.6 o SPDX a partire dalla versione 3.0.1. Per ogni componente richiede tra l'altro autore, nome, versione, nome del file, licenza, dipendenze e un valore hash SHA-512. Le dipendenze vengono risolte in modo ricorsivo, almeno fino al primo componente compreso che si trova al di fuori della Sua fornitura.

CycloneDX o SPDX?

 CycloneDXSPDX
Origine OWASP, standardizzato come ECMA-424 Linux Foundation, versione 2.2.1 come ISO/IEC 5962:2021
Focus sicurezza e catena di fornitura, VEX possibile nello stesso formato in origine licenze e compliance, dalla versione 3 anche sicurezza
Versione attuale 1.7 3.0.1

Entrambi i formati soddisfano il CRA. Decisivo è ciò che i Suoi strumenti e i Suoi clienti elaborano. Per il confronto con le banche dati delle vulnerabilità, ad esempio con OWASP Dependency-Track, è diffuso CycloneDX; i controlli delle licenze lavorano tradizionalmente volentieri con SPDX. La conversione tra i due è possibile, ma non sempre senza perdite.

Generare la SBOM nella build

Se mantenuta a mano, una SBOM è sbagliata già con il successivo aggiornamento di un pacchetto. Il suo posto è nella build, e precisamente per esattamente la versione che viene distribuita. Per .NET c'è lo strumento a riga di comando CycloneDX, per Python cyclonedx-py, per SPDX ad esempio lo sbom-tool di Microsoft:

# .NET: installare lo strumento una volta, poi a ogni build di release

dotnet tool install --global CycloneDX

dotnet-CycloneDX Produkt.sln -o sbom -fn produkt.cdx.json -F Json -t -sn Produkt -sv 2.4.0



# Python: dal requirements.txt

cyclonedx-py requirements requirements.txt --of JSON -o sbom/werkzeug.cdx.json

-sv imposta la versione del prodotto, -t esclude i progetti di test. Poi un piccolo script verifica se la distinta base è completa e fa fallire la build se mancano dati – ad esempio licenze che lo strumento non è riuscito a risolvere:

import json

import sys



with open("sbom/produkt.cdx.json", encoding="utf-8") as datei:

    komponenten = json.load(datei).get("components", [])



fehler = []

for komponente in komponenten:

    name = komponente.get("name", "?")

    for feld in ("version", "purl", "licenses", "hashes"):

        if not komponente.get(feld):

            fehler.append(f"{name}: {feld} fehlt")



print(f"{len(komponenten)} Komponenten geprüft, {len(fehler)} Lücken")

for zeile in fehler:

    print(zeile)

sys.exit(1 if fehler else 0)  # le lacune fanno fallire la build

Che cosa gli strumenti non trovano

Gli strumenti leggono i gestori di pacchetti. Ciò che entra nel prodotto passando accanto a essi manca: DLL copiate, librerie C e C++, moduli acquistati, firmware, ambienti di runtime forniti insieme e tutto ciò che l'installer deposita in aggiunta. Questi componenti li registra una volta in un file integrativo, che la build unisce alla SBOM generata, ad esempio con il comando merge della CLI di CycloneDX. Per gli add-in CAD vale il contrario: le DLL di AutoCAD o di Revit su cui compila non le distribuisce. Non vanno nella Sua SBOM come componente, bensì nella documentazione come prerequisito.

E poi la SBOM deve anche essere usata: la archivi per ogni release con la documentazione tecnica e la confronti costantemente con le banche dati delle vulnerabilità – le nuove vulnerabilità riguardano anche versioni che girano da tempo presso il cliente.

Nota: questo articolo offre una panoramica tecnica e non costituisce consulenza legale.

Errori tipici

  • Generare la SBOM dal codice sorgente invece che dalla build. Allora non descrive ciò che viene effettivamente distribuito.
  • Registrare solo i pacchetti diretti. Molte vulnerabilità si nascondono nelle dipendenze transitive.
  • Una SBOM per tutte le versioni. Ogni versione distribuita ha bisogno della propria.
  • Scrivere le vulnerabilità nella SBOM invece che in un documento VEX separato.
  • Dimenticare DLL copiate e librerie C++, perché nessun gestore di pacchetti le conosce.

Come La aiutiamo

Fonti: regolamento (UE) 2024/2847, art. 3, punto 39, art. 13, par. 24, allegato I, parte II, punto 1, allegato II, punto 9, allegato VII e considerando 77, EUR-Lex; BSI TR-03183-2, versione 2.1.0; CycloneDX; SPDX. Aggiornato a: ottobre 2026.

CONTACT

Seleziona la tua lingua

Primo colloquiofissare oraPrimo colloquiofissare ora