Skip to content

Commit

Permalink
fix: add purl validation to address fuzzing issues (intel#3822)
Browse files Browse the repository at this point in the history
* fix: resolve errors of fuzzing job fuzz_cyclonedx

implemented purl validation to check valid purl strings

Signed-off-by: Meet Soni <[email protected]>
  • Loading branch information
inosmeet authored Feb 15, 2024
1 parent 4479eb0 commit fd80100
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 17 deletions.
43 changes: 27 additions & 16 deletions cve_bin_tool/sbom_manager/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from __future__ import annotations

import re
from collections import defaultdict
from logging import Logger
from pathlib import Path
Expand Down Expand Up @@ -44,7 +45,9 @@ def __init__(
self.cvedb = CVEDB(version_check=False)

def scan_file(self) -> dict[ProductInfo, TriageData]:
LOGGER.info(f"Processing SBOM {self.filename} of type {self.type.upper()}")
self.logger.debug(
f"Processing SBOM {self.filename} of type {self.type.upper()}"
)
modules = []
try:
if Path(self.filename).exists():
Expand All @@ -63,16 +66,15 @@ def scan_file(self) -> dict[ProductInfo, TriageData]:
# Now process list of modules to create [vendor, product, version] tuples
parsed_data: list[ProductInfo] = []
for m in modules:
# Using lower to normalize product names across databases
product, version = m[0].lower(), m[1]
if version != "":
# Now add vendor to create product record....
# print (f"Find vendor for {product} {version}")
vendor_set = self.get_vendor(product)
for vendor in vendor_set:
# if vendor is not None:
parsed_data.append(ProductInfo(vendor, product, version))
# print(vendor,product,version)
if m and m[0]:
# Using lower to normalize product names across databases
product, version = m[0].lower(), m[1]
if version != "":
# Now add vendor to create product record....
vendor_set = self.get_vendor(product)
for vendor in vendor_set:
# if vendor is not None:
parsed_data.append(ProductInfo(vendor, product, version))

for row in parsed_data:
self.sbom_data[row]["default"] = {
Expand All @@ -97,8 +99,14 @@ def get_vendor(self, product: str) -> list:
vendorlist.append("UNKNOWN")
return vendorlist

def is_valid_purl(self, purl_string):
"""Returns true if give purl_string is a valid purl string"""
purl_pattern = r"^\w+://[\w\-.]+/[\w\-.]+(?:/[\w\-.]+)*(?:\?[\w\-.]+=[\w\-.]+(?:&[\w\-.]+=[\w\-.]+)*)?$"
return re.match(purl_pattern, purl_string) is not None

def parse_sbom(self):
"""parse SBOM, using PURL identifiers preferentially if found"""

# Set up SBOM parser
sbom_parser = SBOMParser(sbom_type=self.type)
# Load SBOM
Expand All @@ -121,11 +129,14 @@ def parse_sbom(self):
if ext_ref is not None:
for ref in ext_ref:
if ref[1] == "purl":
# Process purl identifier
purl_info = PackageURL.from_string(ref[2]).to_dict()
if purl_info["name"] and purl_info["version"]:
modules.append([purl_info["name"], purl_info["version"]])
purl_found = True
if self.is_valid_purl(ref[2]):
# Process purl identifier
purl_info = PackageURL.from_string(ref[2]).to_dict()
if purl_info["name"] and purl_info["version"]:
modules.append(
[purl_info["name"], purl_info["version"]]
)
purl_found = True
if not purl_found:
if package.get("version") is not None:
modules.append([package["name"], package["version"]])
Expand Down
2 changes: 1 addition & 1 deletion test/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,7 @@ def test_SBOM(self, caplog):
assert (
"cve_bin_tool",
logging.INFO,
"There are 1 products with known CVEs detected",
"There are 3 products with known CVEs detected",
) in caplog.record_tuples

def test_sbom_detection(self, caplog):
Expand Down

0 comments on commit fd80100

Please sign in to comment.