Skip to content

Commit 6c9ff03

Browse files
authored
feat(output_engine): add --strip-scan-dir (#4930)
Rename --sbom-strip-root to --strip-scan-dir and allow the user to strip scanned directory also on the CVE paths for all outputs (json, csv, console, html, etc.) While at it, drop usage of os.path.splitroot as it is only available since python 3.12 Signed-off-by: Fabrice Fontaine <fabrice.fontaine@orange.com>
1 parent 62dbf4b commit 6c9ff03

11 files changed

Lines changed: 132 additions & 32 deletions

File tree

‎README.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,7 @@ Output:
508508
specify type of software bill of materials (sbom) to generate (default: spdx)
509509
<a href="https://github.com/intel/cve-bin-tool/blob/main/doc/MANUAL.md#--sbom-format">--sbom-format {tag,json,yaml}</a>
510510
specify format of software bill of materials (sbom) to generate (default: tag)
511+
--strip-scan-dir strip scan directory from sbom evidence location paths and CVE paths (useful with a firmware dump)
511512

512513
Vex Output:
513514
Arguments related to Vex output document.

‎cve_bin_tool/cli.py‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -348,9 +348,9 @@ def main(argv=None):
348348
help="specify format of software bill of materials (sbom) to generate (default: tag)",
349349
)
350350
output_group.add_argument(
351-
"--sbom-strip-root",
351+
"--strip-scan-dir",
352352
action="store_true",
353-
help="strip SBOM root from evidence location paths (useful when building SBOM from firmware dump)",
353+
help="strip scan directory from sbom evidence location paths and CVE paths (useful with a firmware dump)",
354354
default=False,
355355
)
356356
vex_output_group = parser.add_argument_group(
@@ -1250,7 +1250,7 @@ def main(argv=None):
12501250
sbom_type=args["sbom_type"],
12511251
sbom_format=args["sbom_format"],
12521252
sbom_root=sbom_root,
1253-
sbom_strip_root=args["sbom_strip_root"],
1253+
strip_scan_dir=args["strip_scan_dir"],
12541254
offline=args["offline"],
12551255
)
12561256

‎cve_bin_tool/output_engine/__init__.py‎

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
intermediate_output,
3333
)
3434
from cve_bin_tool.sbom_manager.generate import SBOMGenerate
35+
from cve_bin_tool.util import strip_path
3536
from cve_bin_tool.version import VERSION
3637
from cve_bin_tool.vex_manager.generate import VEXGenerate
3738

@@ -44,6 +45,7 @@ def save_intermediate(
4445
products_with_cve: int,
4546
products_without_cve: int,
4647
total_files: int,
48+
strip_scan_dir: bool = False,
4749
):
4850
"""Save the intermediate report"""
4951

@@ -54,6 +56,7 @@ def save_intermediate(
5456
products_with_cve,
5557
products_without_cve,
5658
total_files,
59+
strip_scan_dir,
5760
)
5861
with open(filename, "w") as f:
5962
json.dump(inter_output, f, indent=" ")
@@ -62,14 +65,18 @@ def save_intermediate(
6265
def output_csv(
6366
all_cve_data: dict[ProductInfo, CVEData],
6467
all_cve_version_info: dict[str, VersionInfo] | None,
68+
scanned_dir: str,
6569
outfile,
6670
detailed: bool = False,
6771
affected_versions: int = 0,
6872
metrics: bool = False,
73+
strip_scan_dir: bool = False,
6974
):
7075
"""Output a CSV of CVEs"""
7176
formatted_output = format_output(
7277
all_cve_data,
78+
scanned_dir,
79+
strip_scan_dir,
7380
all_cve_version_info,
7481
detailed,
7582
affected_versions,
@@ -123,11 +130,13 @@ def output_pdf(
123130
is_report,
124131
products_with_cve,
125132
all_cve_version_info,
133+
scanned_dir: str,
126134
outfile,
127135
merge_report,
128136
affected_versions: int = 0,
129137
exploits: bool = False,
130138
metrics: bool = False,
139+
strip_scan_dir: bool = False,
131140
all_product_data=None,
132141
):
133142
"""Output a PDF of CVEs"""
@@ -321,7 +330,15 @@ def output_pdf(
321330
"comments": cve.comments,
322331
}
323332
)
324-
path_elements = ", ".join(cve_data["paths"])
333+
if strip_scan_dir:
334+
path_elements = ", ".join(
335+
[
336+
strip_path(path, scanned_dir)
337+
for path in cve_data["paths"]
338+
]
339+
)
340+
else:
341+
path_elements = ", ".join(cve_data["paths"])
325342
for path_element in path_elements.split(","):
326343
path_entry = {
327344
"vendor": product_info.vendor,
@@ -589,11 +606,13 @@ def output_pdf(
589606
is_report,
590607
products_with_cve,
591608
all_cve_version_info,
609+
scanned_dir: str,
592610
outfile,
593611
merge_report,
594612
affected_versions: int = 0,
595613
exploits: bool = False,
596614
all_product_data=None,
615+
strip_scan_dir: bool = False,
597616
):
598617
"""Output a PDF of CVEs
599618
Required module: Reportlab not found"""
@@ -629,6 +648,7 @@ class OutputEngine:
629648
sbom_type (str)
630649
sbom_format (str)
631650
sbom_root (str)
651+
strip_scan_dir (bool)
632652
offline (bool)
633653
634654
Methods:
@@ -667,7 +687,7 @@ def __init__(
667687
sbom_type: str = "spdx",
668688
sbom_format: str = "tag",
669689
sbom_root: str = "CVE_SBOM",
670-
sbom_strip_root: bool = False,
690+
strip_scan_dir: bool = False,
671691
vex_filename: str = "",
672692
vex_type: str = "",
673693
vex_product_info: dict[str, str] = {},
@@ -699,7 +719,7 @@ def __init__(
699719
self.sbom_type = sbom_type
700720
self.sbom_format = sbom_format
701721
self.sbom_root = sbom_root
702-
self.sbom_strip_root = sbom_strip_root
722+
self.strip_scan_dir = strip_scan_dir
703723
self.offline = offline
704724
self.organized_arguements = organized_arguements
705725
self.sbom_packages = {}
@@ -716,43 +736,51 @@ def output_cves(self, outfile, output_type="console"):
716736
output_json(
717737
self.all_cve_data,
718738
self.all_cve_version_info,
739+
self.scanned_dir,
719740
outfile,
720741
self.detailed,
721742
self.affected_versions,
722743
self.metrics,
744+
self.strip_scan_dir,
723745
)
724746
elif output_type == "json2":
725747
output_json2(
726748
self.all_cve_data,
727749
self.all_cve_version_info,
750+
self.scanned_dir,
728751
self.time_of_last_update,
729752
outfile,
730753
self.affected_versions,
731754
self.organized_arguements,
732755
self.detailed,
733756
self.exploits,
734757
self.metrics,
758+
self.strip_scan_dir,
735759
)
736760
elif output_type == "csv":
737761
output_csv(
738762
self.all_cve_data,
739763
self.all_cve_version_info,
764+
self.scanned_dir,
740765
outfile,
741766
self.detailed,
742767
self.affected_versions,
743768
self.metrics,
769+
self.strip_scan_dir,
744770
)
745771
elif output_type == "pdf":
746772
output_pdf(
747773
self.all_cve_data,
748774
self.is_report,
749775
self.products_with_cve,
750776
self.all_cve_version_info,
777+
self.scanned_dir,
751778
outfile,
752779
self.merge_report,
753780
self.affected_versions,
754781
self.exploits,
755782
self.metrics,
783+
self.strip_scan_dir,
756784
)
757785
elif output_type == "html":
758786
output_html(
@@ -768,15 +796,18 @@ def output_cves(self, outfile, output_type="console"):
768796
self.logger,
769797
outfile,
770798
self.affected_versions,
799+
self.strip_scan_dir,
771800
)
772801
else: # console, or anything else that is unrecognised
773802
output_console(
774803
self.all_cve_data,
775804
self.all_cve_version_info,
805+
self.scanned_dir,
776806
self.time_of_last_update,
777807
self.affected_versions,
778808
self.exploits,
779809
self.metrics,
810+
self.strip_scan_dir,
780811
self.all_product_data,
781812
self.offline,
782813
None,
@@ -789,6 +820,7 @@ def output_cves(self, outfile, output_type="console"):
789820
self.append,
790821
self.tag,
791822
self.scanned_dir,
823+
self.strip_scan_dir,
792824
self.products_with_cve,
793825
self.products_without_cve,
794826
self.total_files,
@@ -819,7 +851,7 @@ def output_cves(self, outfile, output_type="console"):
819851
self.sbom_type,
820852
self.sbom_format,
821853
self.sbom_root,
822-
self.sbom_strip_root,
854+
self.strip_scan_dir,
823855
self.logger,
824856
)
825857
sbomgen.generate_sbom()

‎cve_bin_tool/output_engine/console.py‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from ..input_engine import Remarks
1919
from ..linkify import linkify_cve
2020
from ..theme import cve_theme
21-
from ..util import ProductInfo, VersionInfo
21+
from ..util import ProductInfo, VersionInfo, strip_path
2222
from ..version import VERSION
2323
from .util import (
2424
format_path,
@@ -47,10 +47,12 @@ def output_console(*args: Any):
4747
def _output_console_nowrap(
4848
all_cve_data: dict[ProductInfo, CVEData],
4949
all_cve_version_info: dict[str, VersionInfo],
50+
scanned_dir: str,
5051
time_of_last_update: datetime,
5152
affected_versions: int,
5253
exploits: bool = False,
5354
metrics: bool = False,
55+
strip_scan_dir: bool = False,
5456
all_product_data=None,
5557
offline: bool = False,
5658
width: int = None,
@@ -286,13 +288,17 @@ def validate_cell_length(cell_name, cell_type):
286288
color = "green"
287289
for cve_data in cve_by_paths[remarks]:
288290
path_root = format_path(cve_data["paths"])
291+
if strip_scan_dir:
292+
path_root_0 = strip_path(path_root[0], scanned_dir)
293+
else:
294+
path_root_0 = path_root[0]
289295
cells = [
290296
Text.styled(validate_cell_length(cve_data["vendor"], "Vendor "), color),
291297
Text.styled(
292298
validate_cell_length(cve_data["product"], "Product "), color
293299
),
294300
Text.styled(cve_data["version"], color),
295-
Text.styled(validate_cell_length(path_root[0], "Root "), color),
301+
Text.styled(validate_cell_length(path_root_0, "Root "), color),
296302
Text.styled(validate_cell_length(path_root[1], "Path "), color),
297303
]
298304
table.add_row(*cells)

‎cve_bin_tool/output_engine/html.py‎

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
from cve_bin_tool.merge import MergeReports
1616

17-
from ..util import CVEData, ProductInfo, Remarks, VersionInfo
17+
from ..util import CVEData, ProductInfo, Remarks, VersionInfo, strip_path
1818
from ..version import VERSION
1919
from .print_mode import html_print_mode
2020
from .util import group_cve_by_remark
@@ -96,6 +96,7 @@ def output_html(
9696
logger: Logger,
9797
outfile,
9898
affected_versions: int = 0,
99+
strip_scan_dir: bool = False,
99100
):
100101
"""Returns a HTML report for CVE's"""
101102

@@ -403,6 +404,13 @@ def output_html(
403404
if not_affected_cves:
404405
remarks += "not_affected "
405406

407+
if strip_scan_dir:
408+
product_paths = [
409+
strip_path(path, scanned_dir) for path in cve_data["paths"]
410+
]
411+
else:
412+
product_paths = cve_data["paths"]
413+
406414
products_found.append(
407415
product_row.render(
408416
vendor=product_info.vendor,
@@ -418,8 +426,8 @@ def output_html(
418426
),
419427
remarks=remarks,
420428
fix_id=hid,
421-
paths=cve_data["paths"],
422-
len_paths=len(cve_data["paths"]),
429+
paths=product_paths,
430+
len_paths=len(product_paths),
423431
new_cves=new_cves,
424432
mitigated_cves=mitigated_cves,
425433
confirmed_cves=confirmed_cves,
@@ -433,7 +441,7 @@ def output_html(
433441
star_warn = "* vendors guessed by the tool"
434442

435443
# update all_paths
436-
for path in cve_data["paths"]:
444+
for path in product_paths:
437445
all_paths[path].append(hid)
438446

439447
# Dashboard Rendering

0 commit comments

Comments
 (0)