Skip to content

feat(output_engine): add --strip-scan-dir #4930

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,7 @@ Output:
specify type of software bill of materials (sbom) to generate (default: spdx)
<a href="https://github.com/intel/cve-bin-tool/blob/main/doc/MANUAL.md#--sbom-format">--sbom-format {tag,json,yaml}</a>
specify format of software bill of materials (sbom) to generate (default: tag)
--strip-scan-dir strip scan directory from sbom evidence location paths and CVE paths (useful with a firmware dump)

Vex Output:
Arguments related to Vex output document.
Expand Down
6 changes: 3 additions & 3 deletions cve_bin_tool/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,9 +348,9 @@ def main(argv=None):
help="specify format of software bill of materials (sbom) to generate (default: tag)",
)
output_group.add_argument(
"--sbom-strip-root",
"--strip-scan-dir",
action="store_true",
help="strip SBOM root from evidence location paths (useful when building SBOM from firmware dump)",
help="strip scan directory from sbom evidence location paths and CVE paths (useful with a firmware dump)",
default=False,
)
vex_output_group = parser.add_argument_group(
Expand Down Expand Up @@ -1250,7 +1250,7 @@ def main(argv=None):
sbom_type=args["sbom_type"],
sbom_format=args["sbom_format"],
sbom_root=sbom_root,
sbom_strip_root=args["sbom_strip_root"],
strip_scan_dir=args["strip_scan_dir"],
offline=args["offline"],
)

Expand Down
40 changes: 36 additions & 4 deletions cve_bin_tool/output_engine/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
intermediate_output,
)
from cve_bin_tool.sbom_manager.generate import SBOMGenerate
from cve_bin_tool.util import strip_path
from cve_bin_tool.version import VERSION
from cve_bin_tool.vex_manager.generate import VEXGenerate

Expand All @@ -44,6 +45,7 @@ def save_intermediate(
products_with_cve: int,
products_without_cve: int,
total_files: int,
strip_scan_dir: bool = False,
):
"""Save the intermediate report"""

Expand All @@ -54,6 +56,7 @@ def save_intermediate(
products_with_cve,
products_without_cve,
total_files,
strip_scan_dir,
)
with open(filename, "w") as f:
json.dump(inter_output, f, indent=" ")
Expand All @@ -62,14 +65,18 @@ def save_intermediate(
def output_csv(
all_cve_data: dict[ProductInfo, CVEData],
all_cve_version_info: dict[str, VersionInfo] | None,
scanned_dir: str,
outfile,
detailed: bool = False,
affected_versions: int = 0,
metrics: bool = False,
strip_scan_dir: bool = False,
):
"""Output a CSV of CVEs"""
formatted_output = format_output(
all_cve_data,
scanned_dir,
strip_scan_dir,
all_cve_version_info,
detailed,
affected_versions,
Expand Down Expand Up @@ -123,11 +130,13 @@ def output_pdf(
is_report,
products_with_cve,
all_cve_version_info,
scanned_dir: str,
outfile,
merge_report,
affected_versions: int = 0,
exploits: bool = False,
metrics: bool = False,
strip_scan_dir: bool = False,
all_product_data=None,
):
"""Output a PDF of CVEs"""
Expand Down Expand Up @@ -321,7 +330,15 @@ def output_pdf(
"comments": cve.comments,
}
)
path_elements = ", ".join(cve_data["paths"])
if strip_scan_dir:
path_elements = ", ".join(
[
strip_path(path, scanned_dir)
for path in cve_data["paths"]
]
)
else:
path_elements = ", ".join(cve_data["paths"])
for path_element in path_elements.split(","):
path_entry = {
"vendor": product_info.vendor,
Expand Down Expand Up @@ -589,11 +606,13 @@ def output_pdf(
is_report,
products_with_cve,
all_cve_version_info,
scanned_dir: str,
outfile,
merge_report,
affected_versions: int = 0,
exploits: bool = False,
all_product_data=None,
strip_scan_dir: bool = False,
):
"""Output a PDF of CVEs
Required module: Reportlab not found"""
Expand Down Expand Up @@ -629,6 +648,7 @@ class OutputEngine:
sbom_type (str)
sbom_format (str)
sbom_root (str)
strip_scan_dir (bool)
offline (bool)

Methods:
Expand Down Expand Up @@ -667,7 +687,7 @@ def __init__(
sbom_type: str = "spdx",
sbom_format: str = "tag",
sbom_root: str = "CVE_SBOM",
sbom_strip_root: bool = False,
strip_scan_dir: bool = False,
vex_filename: str = "",
vex_type: str = "",
vex_product_info: dict[str, str] = {},
Expand Down Expand Up @@ -699,7 +719,7 @@ def __init__(
self.sbom_type = sbom_type
self.sbom_format = sbom_format
self.sbom_root = sbom_root
self.sbom_strip_root = sbom_strip_root
self.strip_scan_dir = strip_scan_dir
self.offline = offline
self.organized_arguements = organized_arguements
self.sbom_packages = {}
Expand All @@ -716,43 +736,51 @@ def output_cves(self, outfile, output_type="console"):
output_json(
self.all_cve_data,
self.all_cve_version_info,
self.scanned_dir,
outfile,
self.detailed,
self.affected_versions,
self.metrics,
self.strip_scan_dir,
)
elif output_type == "json2":
output_json2(
self.all_cve_data,
self.all_cve_version_info,
self.scanned_dir,
self.time_of_last_update,
outfile,
self.affected_versions,
self.organized_arguements,
self.detailed,
self.exploits,
self.metrics,
self.strip_scan_dir,
)
elif output_type == "csv":
output_csv(
self.all_cve_data,
self.all_cve_version_info,
self.scanned_dir,
outfile,
self.detailed,
self.affected_versions,
self.metrics,
self.strip_scan_dir,
)
elif output_type == "pdf":
output_pdf(
self.all_cve_data,
self.is_report,
self.products_with_cve,
self.all_cve_version_info,
self.scanned_dir,
outfile,
self.merge_report,
self.affected_versions,
self.exploits,
self.metrics,
self.strip_scan_dir,
)
elif output_type == "html":
output_html(
Expand All @@ -768,15 +796,18 @@ def output_cves(self, outfile, output_type="console"):
self.logger,
outfile,
self.affected_versions,
self.strip_scan_dir,
)
else: # console, or anything else that is unrecognised
output_console(
self.all_cve_data,
self.all_cve_version_info,
self.scanned_dir,
self.time_of_last_update,
self.affected_versions,
self.exploits,
self.metrics,
self.strip_scan_dir,
self.all_product_data,
self.offline,
None,
Expand All @@ -789,6 +820,7 @@ def output_cves(self, outfile, output_type="console"):
self.append,
self.tag,
self.scanned_dir,
self.strip_scan_dir,
self.products_with_cve,
self.products_without_cve,
self.total_files,
Expand Down Expand Up @@ -819,7 +851,7 @@ def output_cves(self, outfile, output_type="console"):
self.sbom_type,
self.sbom_format,
self.sbom_root,
self.sbom_strip_root,
self.strip_scan_dir,
self.logger,
)
sbomgen.generate_sbom()
Expand Down
10 changes: 8 additions & 2 deletions cve_bin_tool/output_engine/console.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from ..input_engine import Remarks
from ..linkify import linkify_cve
from ..theme import cve_theme
from ..util import ProductInfo, VersionInfo
from ..util import ProductInfo, VersionInfo, strip_path
from ..version import VERSION
from .util import (
format_path,
Expand Down Expand Up @@ -47,10 +47,12 @@ def output_console(*args: Any):
def _output_console_nowrap(
all_cve_data: dict[ProductInfo, CVEData],
all_cve_version_info: dict[str, VersionInfo],
scanned_dir: str,
time_of_last_update: datetime,
affected_versions: int,
exploits: bool = False,
metrics: bool = False,
strip_scan_dir: bool = False,
all_product_data=None,
offline: bool = False,
width: int = None,
Expand Down Expand Up @@ -286,13 +288,17 @@ def validate_cell_length(cell_name, cell_type):
color = "green"
for cve_data in cve_by_paths[remarks]:
path_root = format_path(cve_data["paths"])
if strip_scan_dir:
path_root_0 = strip_path(path_root[0], scanned_dir)
else:
path_root_0 = path_root[0]
cells = [
Text.styled(validate_cell_length(cve_data["vendor"], "Vendor "), color),
Text.styled(
validate_cell_length(cve_data["product"], "Product "), color
),
Text.styled(cve_data["version"], color),
Text.styled(validate_cell_length(path_root[0], "Root "), color),
Text.styled(validate_cell_length(path_root_0, "Root "), color),
Text.styled(validate_cell_length(path_root[1], "Path "), color),
]
table.add_row(*cells)
Expand Down
16 changes: 12 additions & 4 deletions cve_bin_tool/output_engine/html.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

from cve_bin_tool.merge import MergeReports

from ..util import CVEData, ProductInfo, Remarks, VersionInfo
from ..util import CVEData, ProductInfo, Remarks, VersionInfo, strip_path
from ..version import VERSION
from .print_mode import html_print_mode
from .util import group_cve_by_remark
Expand Down Expand Up @@ -96,6 +96,7 @@ def output_html(
logger: Logger,
outfile,
affected_versions: int = 0,
strip_scan_dir: bool = False,
):
"""Returns a HTML report for CVE's"""

Expand Down Expand Up @@ -403,6 +404,13 @@ def output_html(
if not_affected_cves:
remarks += "not_affected "

if strip_scan_dir:
product_paths = [
strip_path(path, scanned_dir) for path in cve_data["paths"]
]
else:
product_paths = cve_data["paths"]

products_found.append(
product_row.render(
vendor=product_info.vendor,
Expand All @@ -418,8 +426,8 @@ def output_html(
),
remarks=remarks,
fix_id=hid,
paths=cve_data["paths"],
len_paths=len(cve_data["paths"]),
paths=product_paths,
len_paths=len(product_paths),
new_cves=new_cves,
mitigated_cves=mitigated_cves,
confirmed_cves=confirmed_cves,
Expand All @@ -433,7 +441,7 @@ def output_html(
star_warn = "* vendors guessed by the tool"

# update all_paths
for path in cve_data["paths"]:
for path in product_paths:
all_paths[path].append(hid)

# Dashboard Rendering
Expand Down
Loading
Loading