← Retour au blog

Pourquoi votre SBOM échoue à la validation PURL pour les packages npm scopés

· Verimu
PURLCycloneDXNTIASBOMnpm

Si vous générez des SBOM CycloneDX pour des projets Node.js, vous avez peut-être vu votre SBOM passer la validation de schéma mais échouer aux vérifications NTIA des éléments minimaux avec cette erreur :

Component requires at least one valid identifier (PURL or CPE). Both are currently missing or invalid. Path: components.pkg:npm/@types/node@20.11.5.identifiers Rule: Component.identifiers

Le composant est là. La version est là. Le PURL semble correct : pkg:npm/@types/node@20.11.5. Alors quel est le problème ?

Le problème : deux signes @

Un Package URL (PURL) utilise le caractère @ comme séparateur de version. Le format est :

pkg:<type>/<namespace>/<n>@<version>

Quand vous écrivez pkg:npm/@types/node@20.11.5, il y a deux caractères @ dans la chaîne. Un analyseur PURL doit savoir lequel sépare la version. Est-ce @types/node à la version 20.11.5, ou est-ce @types/node@20.11.5 sans version du tout ?

Cette ambiguïté fait que les analyseurs PURL rejettent entièrement l'identifiant. Votre composant n'a effectivement aucun PURL valide, ce qui signifie qu'il échoue à l'exigence NTIA d'« identifiant unique ».

La spécification est explicite

La spécification PURL pour les packages npm traite ce cas directement :

« Le préfixe @ du scope npm est toujours encodé en pourcentage, comme c'était le cas aux premiers jours des scopes npm. »

L'encodage correct pour les packages npm scopés est :

Package ❌ PURL incorrect ✅ PURL correct
@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

Le @ du scope devient %40, ne laissant qu'un seul @ littéral dans tout le PURL — le séparateur de version, sans ambiguïté.

Les packages non scopés comme express@4.18.2 ne sont pas affectés : pkg:npm/express@4.18.2 est déjà correct.

Pourquoi cette erreur est si fréquente

C'est une erreur naturelle. Quand vous regardez @types/node, le préfixe @ fait partie de la façon dont npm affiche et référence le package. Chaque développeur tape npm install @types/node — avec le @ littéral. L'encoder semble contre-intuitif.

Ajoutant à la confusion, certains exemples de PURL circulant sur Internet (et même dans certains fichiers d'exemple CycloneDX) montrent le signe @ non encodé. Les exemples canoniques de la spécification sur GitHub affichent pkg:npm/@angular/animation@12.3.1 — mais le texte normatif de ce même document dit que le @ doit être encodé. C'est le texte de la spécification qui prévaut.

La correction

Si vous développez des outils SBOM, la correction est simple. Lors de la construction d'un PURL pour un package npm scopé, encodez le @ initial en %40 :

function buildPurl(name: string, version: string): string {
  if (name.startsWith('@')) {
    return `pkg:npm/%40${name.slice(1)}@${version}`;
  }
  return `pkg:npm/${name}@${version}`;
}

Une erreur courante est d'utiliser un name.replace('/', '%2F') ou encodeURIComponent global sur le nom entier. Ne faites pas ça non plus — le / entre le namespace et le nom est un séparateur structurel PURL et doit rester non encodé.

Un moyen rapide de vérifier

Après avoir corrigé votre génération de PURL, vous pouvez valider votre SBOM avec :

Les deux détecteront les PURL invalides avant qu'ils ne deviennent un problème de conformité.

Après la correction

Avec le préfixe de scope @ correctement encodé en pourcentage, vos packages npm scopés auront des PURL valides et la vérification d'identifiant NTIA passe sans problème :

✓ 12/12 vérifications des éléments minimaux NTIA réussies

Comment Verimu gère cela

Le générateur de SBOM de Verimu encode correctement les PURL npm scopés selon la spécification PURL — %40 pour le préfixe de scope, / non encodé pour le séparateur de namespace. Chaque SBOM que nous générons passe la validation des éléments minimaux NTIA dès sa création.

Si vous travaillez à la conformité CRA pour l'accès au marché européen, ou si vous voulez simplement des SBOM qui ne sont pas rejetés en production, nous avons déjà résolu ces cas particuliers pour que vous n'ayez pas à le faire.

Commencer gratuitement → ou réserver une démo pour voir Verimu en action.