From 84fc30d620ffa18f8e5e8449431ac17a8886f8a4 Mon Sep 17 00:00:00 2001 From: Merlin Sievers Date: Wed, 23 Apr 2025 13:42:38 +0200 Subject: [PATCH 1/5] Add version list to affected versions, if no range is specified --- cve_bin_tool/cve_scanner.py | 12 ++++++++++++ cve_bin_tool/output_engine/util.py | 4 +++- cve_bin_tool/util.py | 1 + 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/cve_bin_tool/cve_scanner.py b/cve_bin_tool/cve_scanner.py index 0ea093a3cb..68d0372268 100644 --- a/cve_bin_tool/cve_scanner.py +++ b/cve_bin_tool/cve_scanner.py @@ -57,6 +57,7 @@ def __init__( self.products_without_cve = 0 self.all_cve_data = defaultdict(CVEData) self.all_cve_version_info = dict() + self.all_cve_version_list = dict() self.check_exploits = check_exploits self.exploits_list = exploits_list self.disabled_sources = disabled_sources @@ -136,6 +137,15 @@ def get_cves(self, product_info: ProductInfo, triage_data: TriageData): cve_list = list(map(lambda x: x[0], self.cursor.fetchall())) + for cve_number in cve_list: + query = """ + SELECT version FROM cve_range + WHERE CVE_number=? AND versionStartIncluding='' AND versionStartExcluding='' AND versionEndIncluding='' AND versionEndExcluding='' + """ + self.cursor.execute(query, [cve_number]) + affected_versions = list(set(map(lambda x: x[0], self.cursor.fetchall()))) + self.all_cve_version_info[cve_number] = VersionInfo('','','','', affected_versions) + # Check for any ranges query = """ SELECT @@ -208,6 +218,7 @@ def get_cves(self, product_info: ProductInfo, triage_data: TriageData): start_excluding=version_start_excluding, end_including=version_end_including, end_excluding=version_end_excluding, + version_list=[], ) product_info_data: CVEData | None = self.all_cve_data.get(product_info) @@ -252,6 +263,7 @@ def get_cves(self, product_info: ProductInfo, triage_data: TriageData): self.logger.debug( f"{row['cve_number']} already reported from {c.data_source}" ) + self.logger.debug(c) duplicate_found = True break diff --git a/cve_bin_tool/output_engine/util.py b/cve_bin_tool/output_engine/util.py index 3ded2d86fc..82b23fa292 100644 --- a/cve_bin_tool/output_engine/util.py +++ b/cve_bin_tool/output_engine/util.py @@ -123,7 +123,7 @@ def format_version_range(version_info: VersionInfo) -> str: Reference for Interval terminologies: https://en.wikipedia.org/wiki/Interval_(mathematics) """ - (start_including, start_excluding, end_including, end_excluding) = version_info + (start_including, start_excluding, end_including, end_excluding, version_list) = version_info if start_including and end_including: return f"[{start_including} - {end_including}]" if start_including and end_excluding: @@ -140,6 +140,8 @@ def format_version_range(version_info: VersionInfo) -> str: return f"<= {end_including}" if end_excluding: return f"< {end_excluding}" + if version_list: + return 'list: ' + ", ".join(version_list) return "-" diff --git a/cve_bin_tool/util.py b/cve_bin_tool/util.py index 11ee0533f4..c491f8b2ef 100644 --- a/cve_bin_tool/util.py +++ b/cve_bin_tool/util.py @@ -246,6 +246,7 @@ class VersionInfo(NamedTuple): start_excluding: str end_including: str end_excluding: str + version_list: list[str] class CVEData(DefaultDict[str, Union[List[CVE], Set[str]]]): From 58dc47e2969f0be61cadde19034aa8a2ba7a3229 Mon Sep 17 00:00:00 2001 From: Merlin Sievers Date: Wed, 23 Apr 2025 13:48:06 +0200 Subject: [PATCH 2/5] Fix other instances of VersionInfo instantiation --- cve_bin_tool/output_engine/__init__.py | 2 +- cve_bin_tool/output_engine/console.py | 2 +- cve_bin_tool/output_engine/util.py | 2 +- test/test_output_engine.py | 18 +++++++++--------- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/cve_bin_tool/output_engine/__init__.py b/cve_bin_tool/output_engine/__init__.py index eeccc3ba75..5ddd82480d 100644 --- a/cve_bin_tool/output_engine/__init__.py +++ b/cve_bin_tool/output_engine/__init__.py @@ -354,7 +354,7 @@ def output_pdf( except ( KeyError ): # TODO: handle 'UNKNOWN' and some cves more cleanly - version_info = VersionInfo("", "", "", "") + version_info = VersionInfo("", "", "", "", []) cve_by_remarks[cve.remarks][-1].update( {"affected_versions": format_version_range(version_info)} ) diff --git a/cve_bin_tool/output_engine/console.py b/cve_bin_tool/output_engine/console.py index fc28153d96..c95daac0dd 100644 --- a/cve_bin_tool/output_engine/console.py +++ b/cve_bin_tool/output_engine/console.py @@ -203,7 +203,7 @@ def _output_console_nowrap( try: version_info = all_cve_version_info[cve.cve_number] except KeyError: # TODO: handle 'UNKNOWN' and some cves more cleanly - version_info = VersionInfo("", "", "", "") + version_info = VersionInfo("", "", "", "", []) cve_by_remarks[cve.remarks][-1].update( {"affected_versions": format_version_range(version_info)} ) diff --git a/cve_bin_tool/output_engine/util.py b/cve_bin_tool/output_engine/util.py index 82b23fa292..31e05a5da7 100644 --- a/cve_bin_tool/output_engine/util.py +++ b/cve_bin_tool/output_engine/util.py @@ -227,7 +227,7 @@ def format_output( ): version_info = all_cve_version_info[cve.cve_number] else: # TODO: handle 'UNKNOWN' and some cves more cleanly - version_info = VersionInfo("", "", "", "") + version_info = VersionInfo("", "", "", "", []) details["affected_versions"] = format_version_range(version_info) formatted_output.append(details) diff --git a/test/test_output_engine.py b/test/test_output_engine.py index 74b7861a31..92ff3c8472 100644 --- a/test/test_output_engine.py +++ b/test/test_output_engine.py @@ -454,15 +454,15 @@ class TestOutputEngine(unittest.TestCase): } MOCK_ALL_CVE_VERSION_INFO = { - "UNKNOWN": VersionInfo("", "", "", ""), - "CVE-9999-0001": VersionInfo("0.9.0", "", "1.2.0", ""), - "CVE-9999-0002": VersionInfo("0.9.0", "", "", "1.2.0"), - "CVE-9999-0003": VersionInfo("", "0.9.0", "1.2.0", ""), - "CVE-9999-0004": VersionInfo("", "0.9.0", "", "1.2.0"), - "CVE-9999-0005": VersionInfo("0.9.0", "", "", ""), - "CVE-9999-0006": VersionInfo("", "0.9.0", "", ""), - "CVE-9999-0007": VersionInfo("", "", "1.2.0", ""), - "CVE-9999-0008": VersionInfo("", "", "", "1.2.0"), + "UNKNOWN": VersionInfo("", "", "", "", []), + "CVE-9999-0001": VersionInfo("0.9.0", "", "1.2.0", "", []), + "CVE-9999-0002": VersionInfo("0.9.0", "", "", "1.2.0", []), + "CVE-9999-0003": VersionInfo("", "0.9.0", "1.2.0", "", []), + "CVE-9999-0004": VersionInfo("", "0.9.0", "", "1.2.0", []), + "CVE-9999-0005": VersionInfo("0.9.0", "", "", "", []), + "CVE-9999-0006": VersionInfo("", "0.9.0", "", "", []), + "CVE-9999-0007": VersionInfo("", "", "1.2.0", "", []), + "CVE-9999-0008": VersionInfo("", "", "", "1.2.0", []), } MOCK_ORGANIZED_PARAMETERS = { From 0a5b1fe2aa5e9ef2dd1743cbfbd47db596cdf457 Mon Sep 17 00:00:00 2001 From: merlin-sievers Date: Wed, 23 Apr 2025 14:21:06 +0200 Subject: [PATCH 3/5] Remove remnant of previous implementation --- cve_bin_tool/cve_scanner.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/cve_bin_tool/cve_scanner.py b/cve_bin_tool/cve_scanner.py index 68d0372268..ba64715887 100644 --- a/cve_bin_tool/cve_scanner.py +++ b/cve_bin_tool/cve_scanner.py @@ -57,7 +57,6 @@ def __init__( self.products_without_cve = 0 self.all_cve_data = defaultdict(CVEData) self.all_cve_version_info = dict() - self.all_cve_version_list = dict() self.check_exploits = check_exploits self.exploits_list = exploits_list self.disabled_sources = disabled_sources @@ -263,7 +262,6 @@ def get_cves(self, product_info: ProductInfo, triage_data: TriageData): self.logger.debug( f"{row['cve_number']} already reported from {c.data_source}" ) - self.logger.debug(c) duplicate_found = True break From 181d7fa1f01d70ec5a24b89942cec784dd416821 Mon Sep 17 00:00:00 2001 From: Terri Oda Date: Mon, 5 May 2025 12:48:29 -0700 Subject: [PATCH 4/5] chore: fix flake8 issue --- cve_bin_tool/cve_scanner.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cve_bin_tool/cve_scanner.py b/cve_bin_tool/cve_scanner.py index ba64715887..c84c3f9655 100644 --- a/cve_bin_tool/cve_scanner.py +++ b/cve_bin_tool/cve_scanner.py @@ -143,7 +143,7 @@ def get_cves(self, product_info: ProductInfo, triage_data: TriageData): """ self.cursor.execute(query, [cve_number]) affected_versions = list(set(map(lambda x: x[0], self.cursor.fetchall()))) - self.all_cve_version_info[cve_number] = VersionInfo('','','','', affected_versions) + self.all_cve_version_info[cve_number] = VersionInfo('', '', '', '', affected_versions) # Check for any ranges query = """ From f76c64aec1ce3be7650aa8e9f4bdb1252d3c49de Mon Sep 17 00:00:00 2001 From: Merlin Sievers Date: Tue, 6 May 2025 09:56:02 +0200 Subject: [PATCH 5/5] chore: run black formatter --- cve_bin_tool/cve_scanner.py | 4 +++- cve_bin_tool/output_engine/util.py | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/cve_bin_tool/cve_scanner.py b/cve_bin_tool/cve_scanner.py index c84c3f9655..479a31c5c8 100644 --- a/cve_bin_tool/cve_scanner.py +++ b/cve_bin_tool/cve_scanner.py @@ -143,7 +143,9 @@ def get_cves(self, product_info: ProductInfo, triage_data: TriageData): """ self.cursor.execute(query, [cve_number]) affected_versions = list(set(map(lambda x: x[0], self.cursor.fetchall()))) - self.all_cve_version_info[cve_number] = VersionInfo('', '', '', '', affected_versions) + self.all_cve_version_info[cve_number] = VersionInfo( + "", "", "", "", affected_versions + ) # Check for any ranges query = """ diff --git a/cve_bin_tool/output_engine/util.py b/cve_bin_tool/output_engine/util.py index 31e05a5da7..22ca1e884c 100644 --- a/cve_bin_tool/output_engine/util.py +++ b/cve_bin_tool/output_engine/util.py @@ -123,7 +123,9 @@ def format_version_range(version_info: VersionInfo) -> str: Reference for Interval terminologies: https://en.wikipedia.org/wiki/Interval_(mathematics) """ - (start_including, start_excluding, end_including, end_excluding, version_list) = version_info + (start_including, start_excluding, end_including, end_excluding, version_list) = ( + version_info + ) if start_including and end_including: return f"[{start_including} - {end_including}]" if start_including and end_excluding: @@ -141,7 +143,7 @@ def format_version_range(version_info: VersionInfo) -> str: if end_excluding: return f"< {end_excluding}" if version_list: - return 'list: ' + ", ".join(version_list) + return "list: " + ", ".join(version_list) return "-"