From 4bdc1119fb5344da977e5bc1980abdc68f408626 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Stucke?= Date: Mon, 11 Nov 2024 16:13:11 +0100 Subject: [PATCH] feat: added config option to allow CVE matches without version constraints --- src/config/fact-core-config.toml | 2 ++ src/plugins/analysis/cve_lookup/code/cve_lookup.py | 8 ++++++-- src/plugins/analysis/cve_lookup/internal/lookup.py | 11 ++++++----- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/config/fact-core-config.toml b/src/config/fact-core-config.toml index d114a1821..1ba4e420f 100644 --- a/src/config/fact-core-config.toml +++ b/src/config/fact-core-config.toml @@ -110,6 +110,8 @@ processes = 4 [[backend.plugin]] name = "cve_lookup" processes = 4 +# match CVE entries without versions constraints (`false` by default due to the high risk of false positives) +match-any = false [[backend.plugin]] name = "cwe_checker" diff --git a/src/plugins/analysis/cve_lookup/code/cve_lookup.py b/src/plugins/analysis/cve_lookup/code/cve_lookup.py index 489422832..9e01d457d 100644 --- a/src/plugins/analysis/cve_lookup/code/cve_lookup.py +++ b/src/plugins/analysis/cve_lookup/code/cve_lookup.py @@ -4,6 +4,7 @@ from pathlib import Path from typing import TYPE_CHECKING +import config from analysis.PluginBase import AnalysisBasePlugin from helperFunctions.tag import TagColor from plugins.mime_blacklists import MIME_BLACKLIST_NON_EXECUTABLE @@ -31,16 +32,19 @@ class AnalysisPlugin(AnalysisBasePlugin): DESCRIPTION = 'lookup CVE vulnerabilities' MIME_BLACKLIST = MIME_BLACKLIST_NON_EXECUTABLE DEPENDENCIES = ['software_components'] # noqa: RUF012 - VERSION = '0.1.0' + VERSION = '0.2.0' FILE = __file__ + def additional_setup(self): + self.match_any = getattr(config.backend.plugin.get(self.NAME, {}), 'match-any', False) + def process_object(self, file_object: FileObject) -> FileObject: """ Process the given file object and look up vulnerabilities for each software component. """ cves = {'cve_results': {}} connection = DbConnection(f'sqlite:///{DB_PATH}') - lookup = Lookup(file_object, connection) + lookup = Lookup(file_object, connection, match_any=self.match_any) for value in file_object.processed_analysis['software_components']['result'].values(): product = value['meta']['software_name'] version = value['meta']['version'][0] diff --git a/src/plugins/analysis/cve_lookup/internal/lookup.py b/src/plugins/analysis/cve_lookup/internal/lookup.py index e8dad5ee9..d83f00bf9 100644 --- a/src/plugins/analysis/cve_lookup/internal/lookup.py +++ b/src/plugins/analysis/cve_lookup/internal/lookup.py @@ -25,9 +25,10 @@ class Lookup: - def __init__(self, file_object: FileObject, connection: DbConnection): + def __init__(self, file_object: FileObject, connection: DbConnection, match_any: bool = False): self.file_object = file_object self.db_interface = DbInterface(connection) + self.match_any = match_any def lookup_vulnerabilities( self, @@ -38,10 +39,8 @@ def lookup_vulnerabilities( Look up vulnerabilities for a given product and requested version. """ vulnerabilities = {} - product_terms, version = ( - self._generate_search_terms(product_name), - replace_wildcards([requested_version])[0], - ) + product_terms = self._generate_search_terms(product_name) + version = replace_wildcards([requested_version])[0] cpe_matches = self.db_interface.match_cpes(product_terms) if len(cpe_matches) == 0: logging.debug(f'No CPEs were found for product {product_name}') @@ -107,6 +106,8 @@ def _version_in_boundaries(self, associations: list[Association], requested_vers association.version_end_excluding, ] ): + if self.match_any and association.cpe.version == 'ANY': + association_matches.append(association) continue if self._is_version_in_boundaries(association, requested_version): association_matches.append(association)