Match distro packages an SBOM never labelled with an OS - #35
Merged
Conversation
Trivy picks a distro advisory database from an operating-system component, not from package PURLs, so a supplier SBOM listing every rpm on an image reported zero vulnerabilities. Measured on Trivy 0.71.2: 0 findings without the component, 306 with it; SPDX behaves the same (0 -> 166) and needs the SPDXRef-OperatingSystem id prefix, not primaryPackagePurpose. Infer the distro from the packages and scan an enriched copy — the upload itself is never edited, since it backs the conformance verdict and the signature bundle. A second defect surfaced alongside: os-pkgs results are labelled with the distro, which no PURL reconstruction maps, so every distro finding was dropped as "no purl". Fall back to the PURL Trivy attaches to the finding, leaving reconstruction first so existing ecosystems are untouched. Upstream's rewrite of an existing OS version down to its major release is deliberately not ported: centos 7.9.2009, rocky 8.10, alma 9.3 and redhat 8.9 each matched identically with and without the minor.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes the parity gap tracked as #23 (BomLens
enrich-os-context.py).What was broken
Trivy chooses a distro advisory database from an
operating-systemcomponent in the document, not from the package PURLs. A supplier SBOM can list every rpm on an image, each PURL well formed, and report zero vulnerabilities because it never names the distribution. The gap note said our ingest path was "presumed" affected; it is. Reproduced locally against Trivy 0.71.2 with five CentOS 7 rpm PURLs: 0 findings without the component, 306 with it. SPDX uploads behave the same way (0 → 166), and there the OS package is identified by theSPDXRef-OperatingSystemid prefix —primaryPackagePurpose: OPERATING_SYSTEMalone is not read.While recording the fixture a second defect surfaced. Trivy labels an os-pkgs Result with the distro (
centos,alpine), which_build_purl's Type table cannot map, so every distro finding was skipped astrivy_finding_skipped_no_purl— 12 matched findings, 0 persisted. Adding distro tokens to that table would not help: the reconstruction drops the namespace the stored PURL carries (pkg:rpm/centos/openssl@…).What this does
services/os_context.py— infers(distro, version)by voting over distro PURLs and inserts the component, for CycloneDX and SPDX-JSON.tasks/_trivy_input.py— writes the enriched document to a transient per-scan path and hands Trivy that. Wired into all three callers (ingest, source scan, rematch) so a finding cannot appear on one run and vanish on the weekly rematch.vulnerability_matching— falls back to the PURL Trivy attaches to each finding. Reconstruction stays first, so every ecosystem that already matched is byte-for-byte unaffected (pinned by a test where the two disagree).The upload is never edited. It backs the conformance verdict, the signature bundle and the
sbom_cyclonedxartifact, so the enriched copy lives only in the workspace the scan deletes.Deliberate divergences from upstream
rocky 8.10→8). Measured here on centos 7.9.2009, rocky 8.10, alma 9.3 and redhat 8.9 — each matched identically with and without the minor, so a supplier's stated version is left alone. This module only ever adds a component that is missing.distro=qualifier, contributes no vote and the document is scanned as it arrived. A wrong distro produces findings against packages that were never affected, and those are indistinguishable from real ones downstream.Verification
test_reset_demo_scope_dbfailures reproduce onmainunchanged; the others that appeared were order-dependent and did not repeat.Noted, not fixed here
tasks/scan_container.pyhas its own persist path that records every OS package aspkg:apk/{name}@{version}, so rpm and deb images get apk-typed components. No findings are lost (it creates the components itself), so it is out of scope for this change and tracked separately.