diff --git a/src/views/cyclonedx.py b/src/views/cyclonedx.py index 1549121..abef40d 100644 --- a/src/views/cyclonedx.py +++ b/src/views/cyclonedx.py @@ -109,9 +109,28 @@ def cvss_to_rating_method(cvss: CVSS) -> cyclonedx.model.vulnerability.Vulnerabi return cyclonedx.model.vulnerability.VulnerabilityScoreSource.CVSS_V2 return cyclonedx.model.vulnerability.VulnerabilityScoreSource.get_from_vector(cvss.vector_string) + # Add function to delete the "justification:"null" from the cyclonedx files + def clean_sbom(self, cyclonedx): + if isinstance(cyclonedx, dict): + new_dict = {} + for k, v in cyclonedx.items(): + # Remove 'justification' if it's invalid + if k == "justification" and (v is None or str(v).lower() == "null"): + continue # drop the key entirely + if isinstance(v, (dict, list)): + new_dict[k] = self.clean_sbom(v) + else: + new_dict[k] = v + return new_dict + elif isinstance(cyclonedx, list): + return [self.clean_sbom(item) for item in cyclonedx if item is not None] + else: + return cyclonedx + def load_from_dict(self, cyclonedx: dict): """Read data from CycloneDx json parsed format.""" try: + cyclonedx = self.clean_sbom(cyclonedx) self.sbom = Bom.from_json(data=cyclonedx) # type: ignore except Exception as e: print(f"Error parsing CycloneDx format: {e}") @@ -183,8 +202,10 @@ def merge_vulnerabilities_into_controller(self): vuln.add_url(str(advisory.url)) for affect in vulnerability.affects: - if self.ref_dict[affect.ref]: - vuln.add_package(self.ref_dict[affect.ref]) + ref = affect.ref + # Check is the ref in file exist in the dictionnary, if not skip it + if ref in self.ref_dict: + vuln.add_package(self.ref_dict[ref]) if vulnerability.bom_ref.value: self.ref_dict[vulnerability.bom_ref.value] = vuln.id diff --git a/src/views/openvex.py b/src/views/openvex.py index 5385943..af35236 100644 --- a/src/views/openvex.py +++ b/src/views/openvex.py @@ -49,10 +49,8 @@ def parse_package_section(self, product: dict) -> Optional[Package]: def load_from_dict(self, data: dict): if "statements" in data: for statement in data["statements"]: - if "vulnerability" not in statement or "name" not in statement["vulnerability"]: continue - vuln = Vulnerability(statement["vulnerability"]["name"], ["openvex"], "unknown", "unknown") if "description" in statement["vulnerability"]: vuln.add_text(statement["vulnerability"]["description"], "description") @@ -72,7 +70,6 @@ def load_from_dict(self, data: dict): if "products" in statement: for product in statement["products"]: pkg = self.parse_package_section(product) - if pkg is None: continue self.packagesCtrl.add(pkg) @@ -113,9 +110,14 @@ def to_dict(self, strict_export=False, author=None) -> dict: } for (assess_id, assess) in self.assessmentsCtrl.assessments.items(): stmt = assess.to_openvex_dict() - + # Check if the dict is empty, if so skip it. + if stmt is None: + continue vuln = self.vulnerabilitiesCtrl.get(assess.vuln_id) if vuln is not None: + # Check if there is vulnerability in the dict and if it's "none". If so set a empty dict. + if "vulnerability" not in stmt or stmt["vulnerability"] is None: + stmt["vulnerability"] = {} if "description" in vuln.texts: stmt["vulnerability"]["description"] = vuln.texts["description"] elif "summary" in vuln.texts: