Perché il tuo SBOM non supera la validazione PURL per i pacchetti npm con scope
Se stai generando SBOM CycloneDX per progetti Node.js, potresti aver visto il tuo SBOM superare la validazione dello schema ma fallire le verifiche degli elementi minimi NTIA con questo errore:
Il componente c'è. La versione c'è. Il PURL sembra corretto: pkg:npm/@types/node@20.11.5. Allora qual è il problema?
Il problema: due segni @
Un Package URL (PURL) usa il carattere @ come separatore di versione. Il formato è:
pkg:<type>/<namespace>/<n>@<version>
Quando scrivi pkg:npm/@types/node@20.11.5, ci sono due caratteri @ nella stringa. Un parser PURL deve sapere quale separa la versione. È @types/node alla versione 20.11.5, oppure è @types/node@20.11.5 senza alcuna versione?
Questa ambiguità fa sì che i parser PURL rifiutino l'identificatore completamente. Il tuo componente non ha di fatto alcun PURL valido, il che significa che non supera il requisito NTIA di "identificatore unico".
La specifica è esplicita
La specifica PURL per i pacchetti npm affronta questo caso direttamente:
"Il prefisso @ dello scope npm è sempre codificato in percentuale, come avveniva nei primi tempi degli scope npm."
La codifica corretta per i pacchetti npm con scope è:
| Pacchetto | ❌ PURL scorretto | ✅ PURL corretto |
|---|---|---|
@types/node@20.11.5 |
pkg:npm/@types/node@20.11.5 |
pkg:npm/%40types/node@20.11.5 |
@angular/core@17.1.0 |
pkg:npm/@angular/core@17.1.0 |
pkg:npm/%40angular/core@17.1.0 |
@vue/reactivity@3.4.1 |
pkg:npm/@vue/reactivity@3.4.1 |
pkg:npm/%40vue/reactivity@3.4.1 |
Il @ dello scope diventa %40, lasciando esattamente un solo @ letterale nell'intero PURL — inequivocabilmente il separatore di versione.
I pacchetti senza scope come express@4.18.2 non sono interessati: pkg:npm/express@4.18.2 è già corretto.
Perché questo errore è così comune
È un errore naturale. Quando guardi @types/node, il prefisso @ fa parte del modo in cui npm visualizza e referenzia il pacchetto. Ogni sviluppatore digita npm install @types/node — con il @ letterale. Codificarlo sembra sbagliato.
Ad aumentare la confusione, alcuni esempi di PURL che circolano in rete (e persino in alcuni file di esempio CycloneDX) mostrano il segno @ non codificato. Gli esempi canonici della specifica su GitHub mostrano pkg:npm/@angular/animation@12.3.1 — ma il testo normativo dello stesso documento dice che il @ deve essere codificato. Il testo della specifica ha la precedenza.
La correzione
Se stai sviluppando strumenti SBOM, la correzione è semplice. Quando costruisci un PURL per un pacchetto npm con scope, codifica il @ iniziale come %40:
function buildPurl(name: string, version: string): string {
if (name.startsWith('@')) {
return `pkg:npm/%40${name.slice(1)}@${version}`;
}
return `pkg:npm/${name}@${version}`;
}
Un errore comune è usare un name.replace('/', '%2F') generico o encodeURIComponent sull'intero nome. Non farlo — il / tra namespace e nome è un separatore strutturale PURL e deve restare non codificato.
Un modo rapido per verificare
Dopo aver corretto la generazione dei PURL, puoi validare il tuo SBOM con:
- FOSSA NTIA SBOM Validator
- Il parser di riferimento
purl-specsu GitHub
Entrambi rileveranno i PURL non validi prima che diventino un problema di conformità.
Dopo la correzione
Con il prefisso di scope @ correttamente codificato in percentuale, i tuoi pacchetti npm con scope avranno PURL validi e la verifica dell'identificatore NTIA viene superata senza problemi:
Come Verimu gestisce questo
Il generatore di SBOM di Verimu codifica correttamente i PURL npm con scope secondo la specifica PURL — %40 per il prefisso di scope, / non codificato per il separatore di namespace. Ogni SBOM che generiamo supera la validazione degli elementi minimi NTIA fin dalla creazione.
Se stai lavorando alla conformità CRA per l'accesso al mercato europeo, o semplicemente vuoi SBOM che non falliscono la validazione in produzione, abbiamo già risolto questi casi particolari così che tu non debba farlo.
Inizia gratis → o prenota una demo per vedere Verimu in azione.