l3montree-dev / l3montree-dev/devguard

Evaluate the cpe field of CycloneDX components during vulnerability matching

Open
#3,006 4 comments 0 reactions 1 assignee View on GitHub

@timbastin is already working on this.

Since Sep 14, 2026.

feature-request
Dominant language
Go
Stars
161
Forks
43
Avg merge
1d 8h
Merged PRs (30d)
37

Description

Is your feature request related to a problem? Please describe.

Components that can only be identified by CPE are never matched, because DevGuard resolves vulnerabilities exclusively via PURL. This affects any software that is not installed as a package of the distribution.

Two concrete cases:

  1. Software installed from a vendor repository. mongodb-org-server from repo.mongodb.org is an rpm with .el9, but Red Hat does not ship MongoDB and publishes no advisories for it, so pkg:rpm/redhat/mongodb-org-server@... resolves to nothing. MongoDB Inc. publishes CVEs as a CNA, but only into NVD, which is CPE-addressable only.
  2. Images without a package database, e.g. Nix-based ones. Their components are inventoried correctly (pkg:nix/glibc@2.42-67), but no advisory source exists for that PURL type.

Measured on the same CycloneDX document containing one component with cpe:2.3:a:mongodb:mongodb:5.0.0 and no PURL:

Scanner Findings
Grype 23, incl. 2 Critical / 12 High, with CVSS
DevGuard 0

Describe the solution you'd like

Evaluate the cpe field of a CycloneDX component when it is present, in addition to the PURL. This would make CPE-identifiable components resolvable against the CVE data DevGuard already imports.

Beyond the two cases above it would also address a third: Bitnami advisories currently arrive with CVSS 0.0, because Bitnami does not populate the standardized OSV severity field but puts the rating into database_specific:

$ curl -s https://api.osv.dev/v1/vulns/BIT-mongodb-2021-32040 | jq '{severity, database_specific}'
{
  "severity": null,
  "database_specific": {
    "cpes": ["cpe:2.3:a:mongodb:mongodb:*:*:*:*:*:*:*:*"],
    "severity": "High"
  }
}

Bitnami records carry their own CPE. With CPE matching those findings would arrive as the aliased CVEs with a real CVSS vector, instead of unrated BIT-* identifiers. That is the same class of problem as #1881 ("GO Vulnerabilities have always an CVSS of 0"), where the CVSS also sits on the aliased CVE rather than on the matched record.

Describe alternatives you've considered

  • Declaring pkg:bitnami/<name> instead. Works today, DevGuard finds 21 findings for MongoDB 5.0.0. But it states a wrong origin in the SBOM, ties the coverage to a third-party feed, and the findings still come with CVSS 0.0.
  • Resolving CVSS via the alias relation. OSVToCVERelationships already builds CVERelationship entries from osv.Aliases. This would fix the severity, but not the matching, since the aliased CVE record has no PURL either (affected[].package is null for CVE-2021-32040).
  • Reading database_specific.severity. Vendor-specific, and yields only a qualitative label rather than a CVSS vector.

Additional context

Reproducer, a component identified purely by CPE:

{
  "bomFormat": "CycloneDX", "specVersion": "1.5", "version": 1,
  "metadata": { "component": { "type": "container", "name": "image", "bom-ref": "image" } },
  "components": [
    { "type": "operating-system", "name": "redhat", "version": "9.8", "bom-ref": "os" },
    { "type": "application", "name": "mongodb", "version": "5.0.0", "bom-ref": "m",
      "cpe": "cpe:2.3:a:mongodb:mongodb:5.0.0:*:*:*:*:*:*:*" }
  ],
  "dependencies": [
    { "ref": "image", "dependsOn": ["os"] },
    { "ref": "os", "dependsOn": ["m"] }
  ]
}

devguard-scanner sca reports no findings for this. Grype reports 23, including CVE-2021-32040 (CVSS 7.5) and CVE-2025-14847 (CVSS 8.7).

A note on precision. CPE matching is less precise than PURL matching, so it matters which CPEs are used. When a scanner derives CPEs from component names, the result can be noisy: Grype reported 29 findings for an openssl 4.0.0 component in a Nix image, all via matcher=cpe-match against nvd:cpe, for a version that does not exist in NVD. I would suggest matching only against CPEs that are explicitly present in the SBOM, and not deriving them from names. That keeps the responsibility for correctness with whoever authors the SBOM and avoids inheriting that noise for every component without a PURL.

Context: we are packaging RHEL/UBI9-based scratch images and declare the upstream identity of vendor-repo software as a separate component. Everything resolvable by PURL works well, this is the remaining gap.

Environment: ghcr.io/l3montree-dev/devguard/scanner:main, commit 8cf8ad0441e043b6fac4d72748480dabe05479a7

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.