Skip to content

Commit 547b9a3

Browse files
committed
feat(sbom): add purl
Add purl to SBOM For binary checker, try to "guess" it through purl2cpe database Fix #3317 Signed-off-by: Fabrice Fontaine <[email protected]>
1 parent e36aabe commit 547b9a3

File tree

3 files changed

+32
-1
lines changed

3 files changed

+32
-1
lines changed

cve_bin_tool/cvedb.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,34 @@ def update_vendors(self, cve_data):
763763

764764
return updated_severity, updated_affected
765765

766+
def guess_purl(self, vendor, product, version):
767+
query = """
768+
SELECT
769+
distinct purl
770+
FROM purl2cpe
771+
WHERE cpe like ?
772+
"""
773+
cursor = self.db_open_and_get_cursor()
774+
cursor.execute(query, ["%:" + vendor + ":" + product + ":%"])
775+
776+
# Prefer upstream purl (e.g., github, gitlab, sourceforge)
777+
# over distribution specific purl (e.g. debian, ubuntu, fedora)
778+
purl_entries = [x[0] for x in cursor.fetchall()]
779+
preferred_upstream = [
780+
vendor,
781+
f"github/{vendor}",
782+
f"gitlab/{vendor}",
783+
f"sourceforge/{vendor}",
784+
"github",
785+
"gitlab",
786+
"sourceforge",
787+
"",
788+
]
789+
for subs in preferred_upstream:
790+
res = [i for i in purl_entries if f"pkg:{subs}" in i]
791+
if res:
792+
return res[0] + "@" + version
793+
766794
def db_open_and_get_cursor(self) -> sqlite3.Cursor:
767795
"""Opens connection to sqlite database, returns cursor object."""
768796

cve_bin_tool/sbom_manager/generate.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ def generate_sbom(self) -> None:
107107
else:
108108
evidence = path
109109
my_package.set_evidence(evidence)
110+
if product_data.purl:
111+
my_package.set_purl(product_data.purl)
110112
self.sbom_packages[
111113
(
112114
my_package.get_name(),

cve_bin_tool/version_scanner.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,8 +269,9 @@ def run_checkers(self, filename: str, lines: str) -> Iterator[ScanInfo]:
269269
f"{file_path} matched {dummy_checker_name} {version} ({version_results.matched_filename=}, {version_results.matched_contains=})"
270270
)
271271
for vendor, product in checker.VENDOR_PRODUCT:
272+
purl = self.cve_db.guess_purl(vendor, product, version)
272273
yield ScanInfo(
273-
ProductInfo(vendor, product, version),
274+
ProductInfo(vendor, product, version, purl),
274275
file_path,
275276
)
276277

0 commit comments

Comments
 (0)