To map SBOM components to vulnerabilities, normalize each component to a stable identifier such as a purl, query advisory data for that package, test the exact version against affected ranges, then enrich the hits with exploitation and exposure data. Do these in order, and keep unmatched components visible.
Definitions
A purl (Package-URL) is a URL-style identifier that names a package the same way across ecosystems, built from a type, a name and a version, among other parts. A CPE is a product naming scheme used by some vulnerability data, and it was designed around product and vendor names rather than package registries. Matching is the act of joining your component list to advisories.
The pipeline
- Parse and validate. Reject files that do not parse. CycloneDX says a component's purl, if present, must be valid under the purl specification, so a malformed one is a data problem, not a finding.
- Choose the identifier. Prefer the purl when it exists. Fall back to CPE, then to name plus version plus ecosystem. Record which one you used.
- Normalize. Lowercase where the ecosystem is case insensitive, strip qualifiers you do not need for lookup, and keep the original string for audit.
- Query advisory sources. Use ecosystem sources for packages. An OSV style record names an ecosystem and a package, and the name is only meaningful inside its ecosystem, so an npm package and a PyPI package with the same name are different things.
- Test the version. Check the version against each range using the right ordering rules for that ecosystem. Also check any explicit list of affected versions.
- Deduplicate. Merge records that share aliases.
- Enrich. Add exploitation signals and context (see below).
- Report the gaps. List components that matched nothing because the identifier was missing, not because they are clean.
Why step 8 matters
A component with no identifier produces no findings. That looks like good news and is not. Track the count of unmatched components per SBOM, and treat a high share as a quality problem in the file.
Enrichment worth adding
CISA's Known Exploited Vulnerabilities catalog lists CVEs with reliable evidence of active exploitation and a clear remediation step. CISA says organizations should treat it as an input to prioritization. Flagging a match that appears in KEV moves it above a match that merely has a high score.
Try it yourself
Click through it at your own pace, or open it full screen.
Look at how a single finding carries its component, version and fix information together.
A worked mini example
Suppose the SBOM lists an npm package at version 4.17.20 with a valid purl. You query npm advisories, find a record whose range introduces the issue at 4.0.0 and fixes it at 4.17.21, and your version sits inside the range. That is a match. The fixed version tells you the target for remediation.
Safeguard performs SBOM and dependency scanning and then applies reachability analysis, so a match is shown with whether the affected code is called. Try the free scan to see it on your own files.
Quick check
Should I match on CPE or purl?
Use purl for packages when you have it. CPE is a fallback, and name based guesses should be marked lower confidence.
Does zero matches mean no vulnerabilities?
Not by itself. Check how many components had no usable identifier first.
Sources
- Package-URL introduction: what a purl is and why it is used.
- CycloneDX 1.6 JSON reference: purl and cpe component fields.
- OSV schema: package, ecosystem and ranges.
- CISA KEV catalog: inclusion criteria and use.
Last reviewed: 19 October 2026.