SBOM del firmware ESP32: trovare le vulnerabilita note per EN 18031 e CRA
Sia la EN 18031 sia il Cyber Resilience Act ti portano agli stessi due artefatti: un inventario di cio che contiene il firmware e una lista delle vulnerabilita note che lo riguardano. Per il software embedded questo e sempre stato un problema, ma se sviluppi su ESP32, Espressif offre ora una soluzione davvero valida che fa gran parte del lavoro.

Il problema dell'SBOM firmware: la risposta di Espressif
Se immetti un prodotto radio connesso sul mercato UE, due regolamenti convergono ora sulla stessa richiesta. La EN 18031, armonizzata sotto la Direttiva RED e obbligatoria da agosto 2025, impone di dimostrare che il dispositivo non presenta vulnerabilita note sfruttabili. Il Cyber Resilience Act chiede lo stesso risultato e nomina l'artefatto: i prodotti vanno immessi sul mercato senza vulnerabilita note sfruttabili, e i fabbricanti devono redigere una distinta base del software. Nessuno dei due si accontenta delle buone intenzioni: entrambi esigono che tu conosca, in concreto, ogni componente nel firmware e se qualcuno di essi presenti una falla nota.
Per il software applicativo e i container questo e un problema risolto. Un ecosistema maturo (Syft, Grype, Trivy, Dependency-Track) e cresciuto attorno ai package manager e alle immagini Linux, dove ogni dipendenza ha un nome, una versione e un registro in cui cercarla. Il firmware non ha nulla di tutto cio. Il C bare-metal viene incorporato nell'albero del sorgente, i sottomoduli sono ancorati a un commit git e spesso non esistono ne un package manager ne un identificatore registrato. Gli strumenti che rendono banale un SBOM per un'immagine Docker non hanno storicamente nulla a cui aggrapparsi in una build embedded.
Ed e qui che uno dei nomi piu grossi del silicio per l'IoT ha fatto in silenzio la parte difficile per te. Espressif, i cui chip ESP32 sono dentro un'enorme quota dei dispositivi Wi-Fi connessi al mondo, offre uno strumento per SBOM e vulnerabilita integrato direttamente in ESP-IDF. Genera l'inventario dalla tua build reale e lo confronta con il National Vulnerability Database. Non e perfetto, e questo articolo e onesto su dove ti serve ancora un secondo database. Ma se spedisci su un dispositivo Espressif, un lavoro davvero arduo sulla maggior parte delle piattaforme embedded e in gran parte gia fatto per te.
Cosa richiedono davvero EN 18031 e il CRA
I due regimi arrivano all'SBOM da direzioni opposte, e vale la pena vedere esattamente come. Il CRA (Regolamento (UE) 2024/2847) e diretto: l'Allegato I, Parte II, punto 1 impone ai fabbricanti di documentare i componenti "anche redigendo una distinta base del software in un formato di uso comune e leggibile da dispositivo automatico, che copra almeno le dipendenze di primo livello del prodotto."
Quella formula va maneggiata con cura, perche e facile trarne troppo. "Almeno le dipendenze di primo livello" e la profondita minima esplicita dell'SBOM, non l'affermazione che il primo livello basti. Lo stesso obbligo dell'Allegato I e piu ampio della clausola SBOM: devi documentare i componenti contenuti nel prodotto e gestire le vulnerabilita in tutti i componenti integrati (Considerando 34). Una libreria transitiva compilata o collegata staticamente nel firmware e un componente integrato, quindi se una falla nota sfruttabile vive li, elencare solo la dipendenza diretta non assolve il dovere. In pratica vuoi l'inventario piu completo e affidabile che i tuoi strumenti producano, escludendo le dipendenze solo-build o irraggiungibili con una motivazione documentata anziche fermarti al primo livello. Su ESP32 questo peso e in gran parte sollevato: come vedremo, lo strumento di Espressif emette gia il grafo completo delle dipendenze, non solo quelle dirette.
La EN 18031 non usa mai la parola SBOM, ma ti porta allo stesso punto. Il suo requisito e il GEC-1: software e hardware aggiornati senza vulnerabilita note sfruttabili. Non puoi dimostrare che un dispositivo non presenta alcuna vulnerabilita nota senza prima sapere di cosa e composto. L'SBOM non e un documento che lo standard nomina: e il presupposto pratico dell'affermazione che invece esige.
Ed entrambi i regimi convergono su una sola parola: sfruttabile. Il CRA impone che i prodotti siano immessi sul mercato "senza vulnerabilita sfruttabili note": una vulnerabilita "che ha il potenziale di essere effettivamente utilizzata da un avversario in condizioni operative concrete". Non presenti. Sfruttabili. E la distinzione che trasforma un conteggio di CVE spaventoso in una lista breve e difendibile e, come vedremo, e esattamente la linea che lo strumento di Espressif traccia gia per te.
Generare l'SBOM da una build ESP32 reale

Espressif ha integrato tutto questo in ESP-IDF. Lo strumento esp-idf-sbom ha raggiunto la versione 1.2.0 a giugno 2026 ed e classificato come stabile per la produzione. Compila prima il progetto, poi genera l'inventario:
$ idf.py build$ idf.py sbom-createQuesto scrive un file SPDX conforme a NTIA in build/. Per analizzarlo alla ricerca di vulnerabilita note:
$ idf.py sbom-check --spdx-file build/hello_world.spdxLa CLI autonoma offre piu controllo, ed e quella da usare in CI:
$ pip install esp-idf-sbom$ esp-idf-sbom create -o sbom.spdx build/project_description.json$ esp-idf-sbom check sbom.spdxIl dettaglio cruciale e l'input: **project_description.json proviene dalla tua build reale**. L'inventario descrive il firmware che stai per spedire, non un catalogo statico di tutto cio che l'SDK contiene, il che elimina gran parte del rumore prodotto dagli scanner generici.
E va in profondita, non solo in ampiezza. L'SBOM non e un elenco piatto di componenti di primo livello: descrive un pacchetto SPDX per l'applicazione del progetto, il framework ESP-IDF, la toolchain, ogni componente incluso nella build e i sottomoduli git e i subpackage sottostanti, collegati da relazioni SPDX. E il grafo completo delle dipendenze, esattamente la copertura piu profonda del primo livello verso cui puntano gli obblighi piu ampi del CRA.
Scegliere un formato di output
Usa --format per controllare la serializzazione. Scegli CycloneDX se vuoi le dichiarazioni VEX accanto all'inventario:
$ esp-idf-sbom create --format cyclonedx-json -o sbom.cdx.json build/project_description.jsonI valori supportati sono spdx-tag-value@2.2 (predefinito), spdx-json@2.2, spdx-json-ld@3.0.1 e cyclonedx-json@1.6. In CI il controllo esce con codice diverso da zero quando trova una vulnerabilita o un manifest non valido, quindi una build fallita e il segnale per fermarti e analizzare.

Interrogare l'API pubblica di NVD a ogni build e lento e soggetto a limiti di frequenza: sincronizza una volta un mirror locale, poi analizza offline:
$ esp-idf-sbom sync-db$ esp-idf-sbom check --local-db sbom.spdxIl mirror occupa circa 900 MB: un buon compromesso per scansioni riproducibili e utilizzabili offline. Espressif pubblica anche una GitHub Action ufficiale, espressif/esp-idf-sbom-action, e gestisce una dashboard di sicurezza quotidiana sulle release di ESP-IDF, utile come riscontro indipendente.
Come si presenta una scansione reale
La documentazione di Espressif illustra un progetto ancorato a una versione obsoleta di libexpat 2.6.0. L'esecuzione del controllo stampa un riepilogo direttamente nel terminale:
Report summary┌───────────────────────────────────┬────────────────────────────────────────────────────────────────┐│ Date: │ 2024-11-13T14:20:23Z ││ Project name: │ project-expat_test ││ Project version: │ 6c23b9cdb268 ││ Vulnerability database: │ NATIONAL VULNERABILITY DATABASE REST API (https://nvd.nist.gov)││ Generated by tool: │ esp-idf-sbom (0.19.1) ││ Generated with command: │ esp-idf-sbom check sbom.spdx ││ Number of scanned packages: │ 32 │├───────────────────────────────────┼────────────────────────────────────────────────────────────────┤│ CRITICAL CVEs found: │ CVE-2024-45491, CVE-2024-45492 ││ Packages affect by CRITICAL CVEs: │ libexpat ││ Number of CRITICAL CVEs: │ 2 │├───────────────────────────────────┼────────────────────────────────────────────────────────────────┤│ HIGH CVEs found: │ CVE-2024-45490 ││ Packages affect by HIGH CVEs: │ libexpat ││ Number of HIGH CVEs: │ 1 │├───────────────────────────────────┼────────────────────────────────────────────────────────────────┤│ MEDIUM CVEs found: │ ││ Packages affect by MEDIUM CVEs: │ ││ Number of MEDIUM CVEs: │ 0 │├───────────────────────────────────┼────────────────────────────────────────────────────────────────┤│ LOW CVEs found: │ ││ Packages affect by LOW CVEs: │ ││ Number of LOW CVEs: │ 0 │├───────────────────────────────────┼────────────────────────────────────────────────────────────────┤│ UNKNOWN CVEs found: │ ││ Packages affect by UNKNOWN CVEs: │ ││ Number of UNKNOWN CVEs: │ 0 │├───────────────────────────────────┼────────────────────────────────────────────────────────────────┤│ All CVEs found: │ CVE-2024-45491, CVE-2024-45492, CVE-2024-45490 ││ All packages affect by CVEs: │ libexpat ││ Total number of CVEs: │ 3 │└───────────────────────────────────┴────────────────────────────────────────────────────────────────┘ Packages with Identified Vulnerabilities┌──────────┬─────────┬────────────────┬────────────┬───────────────┬───────────────────────────────────────────────────┐│ Package │ Version │ CVE ID │ Base Score │ Base Severity │ Information │├──────────┼─────────┼────────────────┼────────────┼───────────────┼───────────────────────────────────────────────────┤│ │ │ │ │ │ Status Analyzed ││ │ │ │ │ │ CVSS 3.1 ││ │ │ │ │ │ Vec. CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/... ││ libexpat │ 2.6.0 │ CVE-2024-45491 │ 9.8 │ CRITICAL │ CPE cpe:2.3:a:libexpat_project:libexpat:2... ││ │ │ │ │ │ Link https://nvd.nist.gov/vuln/detail/CVE-... ││ │ │ │ │ │ Desc. An issue was discovered in libexpat ││ │ │ │ │ │ before 2.6.3. dtdCopy in xmlparse.c... │├──────────┼─────────┼────────────────┼────────────┼───────────────┼───────────────────────────────────────────────────┤│ │ │ │ │ │ Status Analyzed ││ │ │ │ │ │ CVSS 3.1 ││ │ │ │ │ │ Vec. CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/... ││ libexpat │ 2.6.0 │ CVE-2024-45492 │ 9.8 │ CRITICAL │ CPE cpe:2.3:a:libexpat_project:libexpat:2... ││ │ │ │ │ │ Link https://nvd.nist.gov/vuln/detail/CVE-... ││ │ │ │ │ │ Desc. An issue was discovered in libexpat ││ │ │ │ │ │ before 2.6.3. nextScaffoldPart in... │├──────────┼─────────┼────────────────┼────────────┼───────────────┼───────────────────────────────────────────────────┤│ │ │ │ │ │ Status Analyzed ││ │ │ │ │ │ CVSS 3.1 ││ │ │ │ │ │ Vec. CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/... ││ libexpat │ 2.6.0 │ CVE-2024-45490 │ 7.5 │ HIGH │ CPE cpe:2.3:a:libexpat_project:libexpat:2... ││ │ │ │ │ │ Link https://nvd.nist.gov/vuln/detail/CVE-... ││ │ │ │ │ │ Desc. An issue was discovered in libexpat ││ │ │ │ │ │ before 2.6.3. xmlparse.c does not... │└──────────┴─────────┴────────────────┴────────────┴───────────────┴───────────────────────────────────────────────────┘ Newly identified vulnerabilities. Further analysis may be required for confirmation.Trentadue pacchetti analizzati, tre CVE per un solo parser XML, confrontati sull'identificatore di piattaforma cpe:2.3:a:libexpat_project:libexpat:2.6.0. Su un prodotto reale con decine di componenti, una scansione non filtrata e il motivo per cui i team si ritrovano a fissare cento risultati la settimana prima del lancio, ed e qui che lo strumento di Espressif si comporta meglio della maggior parte degli altri.
La qualita migliore e la vulnerabilita che si rifiuta di segnalare
Dalla documentazione dello strumento: "vengono esaminati solo i pacchetti con una relazione diretta o indiretta con il pacchetto del progetto." L'esempio che ogni sviluppatore ESP32 riconoscera: se mbedtls viene compilato per via delle dipendenze ma non e collegato nel binario finale, compare nell'SBOM ma non e raggiungibile dal pacchetto radice, quindi e registrato nell'inventario ma non segnalato come vulnerabilita. E esattamente la linea che il GEC-1 della EN 18031 e la definizione di sfruttabile del CRA chiedono di tracciare, e che la maggior parte degli scanner generici non traccia.
Alcune opzioni ti permettono di spostare quella linea consapevolmente, a seconda di quanto ampia vuoi la rete:
--rem-unusede quella che userai piu spesso. Rimuove del tutto dall'SBOM i componenti che non raggiungono il binario finale, cosi l'inventario che spedisci descrive solo cio che e davvero nel firmware. E l'opzione che mantiene onesta la distinta base e mirata la scansione.--check-all-packagesva nella direzione opposta, estendendo il controllo delle vulnerabilita a ogni pacchetto dell'inventario anziche al solo insieme raggiungibile. Utile quando vuoi deliberatamente il quadro completo, non solo quello spedito.--extended-scancerca inoltre nelle descrizioni dei CVE che NVD non ha finito di analizzare. Davvero utile come allerta precoce, ma troppo rumoroso per costituire da solo la tua evidenza di conformita.
Un database non basta, e la soluzione e gia nel tuo SBOM

Ecco il limite onesto, detto chiaramente: il controllo integrato interroga solo il National Vulnerability Database e confronta i componenti tramite CPE, l'identificatore di piattaforma che hai visto nel report qui sopra. Non interroga OSV, il GitHub Advisory Database o OSS Index.
Nel 2026 questo pesa piu che nel 2023. Ad aprile 2026 il NIST stesso lo ha confermato: "Dall'inizio del 2024 l'NVD ha accumulato un arretrato significativo di CVE non arricchiti... non siamo riusciti a smaltirlo." Un CVE che non riceve mai dati CPE non puo essere intercettato da uno scanner basato su CPE, e questo colpisce soprattutto il mondo embedded, dove le librerie sono spesso incorporate nell'albero del progetto o ancorate a un commit git senza alcun CPE registrato.
La buona notizia: lo strumento emette gia l'identificatore che risolve il problema
Accanto a ogni CPE, esp-idf-sbom emette un Package URL (PURL), ad esempio pkg:github/madler/zlib@<versione>. Un PURL punta al repository sorgente originale, ed e la chiave che apre i database che il CPE non raggiunge. OSV (osv.dev) associa le vulnerabilita agli intervalli di commit git, quindi puo intercettare una copia vulnerabile di una libreria C incorporata nel tuo albero e priva di qualsiasi CPE. Il GitHub Advisory Database raccoglie invece gli avvisi diretti dei manutentori, a volte prima di NVD.
| Fonte | Corrispondenza tramite | Intercetta | Punto cieco |
|---|---|---|---|
NVD (integrato in | Identificatore di prodotto CPE | Componenti noti con CPE registrato e stringa di versione pulita | CVE non arricchiti; codice incorporato; fork con nome fornitore diverso |
OSV | Intervallo di commit git, PURL, pacchetto di ecosistema | C/C++ incorporato e sottomoduli privi di qualsiasi CPE | Dipende dalla qualita dei link alle patch; richiede la cronologia git |
GitHub Advisory Database | Pacchetto di ecosistema, identificatore GHSA | Avvisi diretti dei manutentori, a volte prima di NVD | Nessun ecosistema C/C++ nativo; per il resto rispecchia i CVE |
Non e un espediente: e l'uso previsto di una distinta base portabile e leggibile da una macchina. Genera una volta con lo strumento di Espressif, poi interroga piu database con gli identificatori che ti ha gia fornito.
Da cento risultati a una lista breve e difendibile

Una scansione grezza ti dice quali componenti contengono una vulnerabilita. Nessuna delle due norme pone quella domanda; entrambe chiedono se sia sfruttabile nel prodotto che stai spedendo. Ridurre quella lista con la triage e il punto in cui la pipeline da SBOM a CVE ripaga lo sforzo. Per ogni risultato, poniti tre domande in ordine: il codice vulnerabile e compilato in questa build? Se lo e, la funzionalita interessata e abilitata nella tua configurazione? Se lo e, e raggiungibile da un avversario in condizioni concrete? Una falla in un handshake TLS 1.3 non e sfruttabile in un firmware che non negozia mai TLS 1.3.
Metti per iscritto il verdetto in un formato leggibile da una macchina
Una decisione che non puoi mostrare e una decisione che non hai preso. VEX, una dichiarazione di sfruttabilita delle vulnerabilita, registra l'esito in forma strutturata. Ogni risultato riceve uno di quattro stati: not_affected, affected, fixed o under_investigation. Quando dichiari not_affected devi fornire una delle cinque giustificazioni standard:
component_not_present: il componente non e presente nel prodotto spedito.vulnerable_code_not_present: il componente e incluso, ma il codice vulnerabile no.vulnerable_code_not_in_execute_path: il codice vulnerabile e presente ma non viene mai eseguito.vulnerable_code_cannot_be_controlled_by_adversary: viene eseguito, ma un attaccante non puo raggiungerlo o influenzarlo.inline_mitigations_already_exist: protezioni integrate impediscono lo sfruttamento.
esp-idf-sbom emette dichiarazioni VEX not_affected nel suo output CycloneDX e supporta liste di esclusione per singolo CVE con motivazioni documentate in SPDX. Cosi la giustificazione che hai ragionato in una revisione di progetto viaggia con la distinta base, leggibile da una macchina, pronta per un'autorita di vigilanza del mercato o un integratore a valle. Se hai gia compilato una tabella delle vulnerabilita EN 18031, queste categorie ti sembreranno familiari: VEX e lo stesso ragionamento in una forma che una macchina puo consumare.
Domande frequenti
La EN 18031 mi obbliga a produrre un SBOM?
No. Software bill of materials e SBOM non compaiono in EN 18031-1, -2 o -3. Lo standard richiede il GEC-1: nessuna vulnerabilita nota sfruttabile. Non puoi dimostrarlo senza un inventario dei componenti, quindi l'SBOM e il modo naturale di produrre l'evidenza: semplicemente non e l'oggetto della richiesta.
Il CRA richiede un grafo completo delle dipendenze?
Non come regola generale, ma "basta il primo livello" e la conclusione sbagliata. L'Allegato I Parte II(1) fissa la profondita minima esplicita dell'SBOM ad "almeno le dipendenze di primo livello". A parte questo, pero, il CRA ti obbliga a documentare i componenti contenuti nel prodotto e a gestire le vulnerabilita in tutti i componenti integrati (Considerando 34). Una libreria transitiva inclusa nel firmware e un componente integrato, quindi se una falla nota sfruttabile vive li, elencare solo la dipendenza diretta non assolve il tuo dovere. La posizione difendibile: metti ogni dipendenza diretta nell'SBOM come minimo, poi inventaria anche i componenti transitivi spediti, escludendo quelli solo-build o irraggiungibili con una motivazione documentata.
L'SBOM deve usare SPDX o CycloneDX?
Il CRA parla solo di "un formato di uso comune e leggibile da dispositivo automatico". L'articolo 13(24) autorizza la Commissione a specificare un formato con atto di esecuzione; nessuno e stato adottato. Entrambi i formati soddisfano il requisito, e esp-idf-sbom li produce entrambi.
Devo pubblicare il mio SBOM?
No. Secondo il CRA appartiene alla documentazione tecnica (Allegato VII), fornita a un'autorita di vigilanza del mercato su richiesta motivata. Renderla disponibile agli utenti e esplicitamente facoltativo.
Lo scanner ha segnalato mbedtls ma non lo colleghiamo mai. E un bug?
Quasi certamente no; per impostazione predefinita non dovrebbe essere segnalato affatto. esp-idf-sbom controlla solo i pacchetti raggiungibili dal progetto radice: un componente compilato per via di una dipendenza ma mai collegato compare nell'SBOM e viene saltato dal controllo. vulnerable_code_not_present e la giustificazione VEX che registra onestamente il risultato.
Quando si applicano davvero gli obblighi del CRA?
E entrato in vigore il 10 dicembre 2024. Gli obblighi di segnalazione (articolo 14) si applicano dall'11 settembre 2026, e gli obblighi principali, compresi i requisiti essenziali dell'Allegato I, dall'11 dicembre 2027. La conformita alla EN 18031 ai sensi della Direttiva RED e obbligatoria dal 1 agosto 2025, quindi per la maggior parte dei prodotti radio connessi questo lavoro e gia rilevante oggi.
Dai risultati della scansione all'evidenza di conformita
Cio che lo strumento di Espressif non puo fare da solo e vedere i CVE che NVD non ha arricchito, o la libreria incorporata senza CPE. Non e un motivo di pessimismo: la distinta base che produce contiene gia i PURL di cui quegli altri database hanno bisogno. Genera una volta, interroga ampiamente, giudica onestamente e scrivi il verdetto dove una macchina possa leggerlo. Questa e la meta ingegneristica. Trasformare quei risultati analizzati in documentazione tecnica che regga una verifica di vigilanza del mercato e la meta di conformita, ed e li che vive RedComply.
RedComply struttura l'intera valutazione EN 18031, inclusa la sezione sulla gestione delle vulnerabilita guidata dal GEC-1. Importa i tuoi risultati, registra ciascuno come rimediato, mitigato, accettato o non sfruttabile, e lascia che la piattaforma porti quelle giustificazioni fino al piano di test e alla Dichiarazione di Conformita. L'assistente AI legge le evidenze che carichi (report di scansione, avvisi, note di progettazione) e ti aiuta a scrivere giustificazioni che citano il documento reale.
Tabelle delle vulnerabilita strutturate secondo le categorie di rimedio della EN 18031
Una Knowledge Base che tiene report di scansione e avvisi dei fornitori accanto alla valutazione che sostengono
Alberi decisionali e piani di test che ereditano i verdetti sulle vulnerabilita invece di richiederli due volte
Generazione della Dichiarazione di Conformita a partire dalla documentazione gia completata
Esegui la scansione con lo strumento di Espressif. Porta i verdetti in RedComply e lascia che la documentazione si costruisca da sola. Visita redcomply.com per vedere come la sezione sulla gestione delle vulnerabilita si inserisce in una valutazione EN 18031 completa.
