Developer Perruer has continued the archived Minefield project from BitBom under the new name Sapper, adding critical fixes that enable accurate answers to the question of which products are affected by a given CVE through direct or transitive dependencies.
The original tool built a dependency graph from SBOMs where each package became a node identified by purl, storing parents and children in roaring bitmaps. Vulnerabilities from OSV were attached as additional nodes, turning impact queries into upward traversals from vulnerable packages. Minefield precomputed transitive closures using Tarjan's algorithm to collapse strongly connected components followed by dynamic programming, achieving O(n + m) performance.
SBOM Direction Bug Discovered After protobom Update
After updating the protobom library from 0.5 to 0.6, end-to-end tests showed dramatically inflated results: instead of six dependent packages, the system reported sixty. Investigation revealed that protobom 0.5 had silently dropped dependsOn edges from CycloneDX files, while version 0.6 correctly parsed both CycloneDX and SPDX relationships. The original Minefield code treated every edge as “from depends on to,” which is correct for CycloneDX but incorrect for SPDX predicates such as runtimeDependencyOf or containedBy that reverse the direction.
The fix introduces an explicit direction table that classifies each sbom.Edge_Type as fromDependsOnTo, toDependsOnFrom, or notADependency. After correction, test expectations were updated and independently verified by a Python script that parsed the same SBOM JSON files according to the CycloneDX and SPDX specifications.
Additional Reliability Fixes
- Replaced mattn/go-sqlite3 with glebarez/sqlite to produce a single static binary without cgo.
- Configured in-memory databases to use a single connection and enabled WAL mode with busy_timeout for file-based storage.
- Fixed OSV range sorting that previously compared versions from the wrong slice, causing incorrect vulnerability status for multi-range records and Go pseudo-versions.
- Added a package-name index that reduced full Go OSV database loading from tens of minutes to 7–8 seconds.
The new sapper report command traverses the cached graph to produce prioritized vulnerability impact lists ordered first by CISA KEV presence, then by EPSS score, then by number of affected products. It merges duplicate findings via alias relationships and respects OpenVEX documents that mark specific products as not affected.
Sapper remains fully air-gapped, accepts CycloneDX and SPDX files or archives, and can ingest KEV, EPSS, and OSV data. The project is available at github.com/Perruer/sapper under the Apache-2.0 license.
