diff options
| author | Adam Janovsky | 2021-12-07 17:03:54 +0100 |
|---|---|---|
| committer | Adam Janovsky | 2021-12-07 17:03:54 +0100 |
| commit | 04f676c697beae7a6f2c41543d0dea9503fd9e75 (patch) | |
| tree | ff06d683f7b77482d4d7f37b4d65a8637987e60a | |
| parent | 6865ad4dafe884fcc89b00342f98e54b74e912b6 (diff) | |
| download | sec-certs-04f676c697beae7a6f2c41543d0dea9503fd9e75.tar.gz sec-certs-04f676c697beae7a6f2c41543d0dea9503fd9e75.tar.zst sec-certs-04f676c697beae7a6f2c41543d0dea9503fd9e75.zip | |
Slightly more strict CPE matching, less FP
| -rw-r--r-- | sec_certs/dataset/dataset.py | 13 | ||||
| -rw-r--r-- | sec_certs/model/cpe_matching.py | 11 |
2 files changed, 19 insertions, 5 deletions
diff --git a/sec_certs/dataset/dataset.py b/sec_certs/dataset/dataset.py index ade17bb5..e02f6e8e 100644 --- a/sec_certs/dataset/dataset.py +++ b/sec_certs/dataset/dataset.py @@ -13,6 +13,7 @@ import requests import sec_certs.helpers as helpers import sec_certs.constants as constants import sec_certs.parallel_processing as cert_processing +from sec_certs.sample.cpe import CPE from sec_certs.sample.certificate import Certificate from sec_certs.serialization.json import ComplexSerializableType @@ -180,6 +181,16 @@ class Dataset(ABC, ComplexSerializableType): cert.compute_heuristics_version() def _compute_cpe_matches(self, download_fresh_cpes: bool = False) -> Tuple[CPEClassifier, CPEDataset]: + def filter_condition(cpe: CPE) -> bool: + """ + Filters out very weak CPE matches that don't improve our database. + """ + if cpe.title and (cpe.version == '-' or cpe.version == '*') and not any(char.isdigit() for char in cpe.title): + return False + elif not cpe.title and (cpe.version == '-' or cpe.version == '*') and not any(char.isdigit() for char in cpe.item_name): + return False + return True + logger.info('Computing heuristics: Finding CPE matches for certificates') cpe_dset = self._prepare_cpe_dataset(download_fresh_cpes) if not cpe_dset.was_enhanced_with_vuln_cpes: @@ -187,7 +198,7 @@ class Dataset(ABC, ComplexSerializableType): cpe_dset.enhance_with_cpes_from_cve_dataset(cve_dset) clf = CPEClassifier(config.cpe_matching_threshold, config.cpe_n_max_matches) - clf.fit([x for x in cpe_dset]) + clf.fit([x for x in cpe_dset if filter_condition(x)]) for cert in tqdm.tqdm(self, desc='Predicting CPE matches with the classifier'): cert.compute_heuristics_cpe_match(clf) diff --git a/sec_certs/model/cpe_matching.py b/sec_certs/model/cpe_matching.py index fb7c211e..bbf61ad7 100644 --- a/sec_certs/model/cpe_matching.py +++ b/sec_certs/model/cpe_matching.py @@ -98,9 +98,6 @@ class CPEClassifier(BaseEstimator): @param relax_title: bool @return: """ - if product_name == 'VMware® ESXi 4.0 Update 1 and vCenter Server 4.0 Update 1': - print('geee') - sanitized_vendor = CPEClassifier._discard_trademark_symbols(vendor).lower() if vendor else vendor sanitized_product_name = CPEClassifier._fully_sanitize_string(product_name) if product_name else product_name candidate_vendors = self.get_candidate_list_of_vendors(sanitized_vendor) @@ -223,11 +220,17 @@ class CPEClassifier(BaseEstimator): """ def is_cpe_version_among_cert_versions(cpe_version: Optional[str], cert_versions: List[str]) -> bool: + def simple_startswith(seeked_version: str, checked_string: str) -> bool: + if seeked_version == checked_string: + return True + else: + return checked_string.startswith(seeked_version) and not checked_string[len(seeked_version)].isdigit() + if not cpe_version: return False just_numbers = r'(\d{1,5})(\.\d{1,5})' # TODO: The use of this should be double-checked for v in cert_versions: - if (v.startswith(cpe_version) and re.search(just_numbers, cpe_version)) or cpe_version.startswith(v): + if (simple_startswith(v, cpe_version) and re.search(just_numbers, cpe_version)) or simple_startswith(cpe_version, v): return True return False |
