diff --git a/vulnerabilities/importers/__init__.py b/vulnerabilities/importers/__init__.py index 8aa9961d5..b65bab937 100644 --- a/vulnerabilities/importers/__init__.py +++ b/vulnerabilities/importers/__init__.py @@ -63,6 +63,7 @@ from vulnerabilities.pipelines.v2_importers import pysec_importer as pysec_importer_v2 from vulnerabilities.pipelines.v2_importers import redhat_importer as redhat_importer_v2 from vulnerabilities.pipelines.v2_importers import ruby_importer as ruby_importer_v2 +from vulnerabilities.pipelines.v2_importers import suse_score_importer as suse_score_importer_v2 from vulnerabilities.pipelines.v2_importers import vulnrichment_importer as vulnrichment_importer_v2 from vulnerabilities.pipelines.v2_importers import xen_importer as xen_importer_v2 from vulnerabilities.utils import create_registry @@ -90,6 +91,7 @@ ruby_importer_v2.RubyImporterPipeline, epss_importer_v2.EPSSImporterPipeline, mattermost_importer_v2.MattermostImporterPipeline, + suse_score_importer_v2.SUSESeverityScoreImporterPipeline, nvd_importer.NVDImporterPipeline, github_importer.GitHubAPIImporterPipeline, gitlab_importer.GitLabImporterPipeline, diff --git a/vulnerabilities/pipelines/v2_importers/suse_score_importer.py b/vulnerabilities/pipelines/v2_importers/suse_score_importer.py new file mode 100644 index 000000000..d5c1da768 --- /dev/null +++ b/vulnerabilities/pipelines/v2_importers/suse_score_importer.py @@ -0,0 +1,72 @@ +# +# Copyright (c) nexB Inc. and others. All rights reserved. +# VulnerableCode is a trademark of nexB Inc. +# SPDX-License-Identifier: Apache-2.0 +# See http://www.apache.org/licenses/LICENSE-2.0 for the license text. +# See https://github.com/aboutcode-org/vulnerablecode for support or download. +# See https://aboutcode.org for more information about nexB OSS projects. +# + +from typing import Iterable + +from vulnerabilities import severity_systems +from vulnerabilities.importer import AdvisoryData +from vulnerabilities.importer import ReferenceV2 +from vulnerabilities.importer import VulnerabilitySeverity +from vulnerabilities.management.commands.commit_export import logger +from vulnerabilities.pipelines import VulnerableCodeBaseImporterPipelineV2 +from vulnerabilities.utils import fetch_yaml + + +class SUSESeverityScoreImporterPipeline(VulnerableCodeBaseImporterPipelineV2): + spdx_license_expression = "CC-BY-4.0" + license_url = "https://ftp.suse.com/pub/projects/security/yaml/LICENSE" + pipeline_id = "suse_importer_v2" + url = "https://ftp.suse.com/pub/projects/security/yaml/suse-cvss-scores.yaml" + + @classmethod + def steps(cls): + return ( + cls.fetch_advisories, + cls.collect_and_store_advisories, + ) + + def fetch_advisories(self): + self.score_data = fetch_yaml(self.url) + + def advisories_count(self): + return sum(1 for _ in self.score_data) + + def collect_advisories(self) -> Iterable[AdvisoryData]: + systems_by_version = { + "2.0": severity_systems.CVSSV2, + "3": severity_systems.CVSSV3, + "3.1": severity_systems.CVSSV31, + "4": severity_systems.CVSSV4, + } + + for cve_id in self.score_data or []: + severities = [] + for cvss_score in self.score_data[cve_id].get("cvss") or []: + cvss_version = cvss_score.get("version") or "" + scoring_system = systems_by_version.get(cvss_version) + if not scoring_system: + logger.error(f"Unsupported CVSS version: {cvss_version}") + continue + base_score = str(cvss_score.get("score") or "") + vector = str(cvss_score.get("vector") or "") + score = VulnerabilitySeverity( + system=scoring_system, + value=base_score, + scoring_elements=vector, + ) + severities.append(score) + + yield AdvisoryData( + advisory_id=cve_id, + aliases=[], + summary="", + severities=severities, + references_v2=[ReferenceV2(reference_id=cve_id, url=self.url)], + url=self.url, + ) diff --git a/vulnerabilities/tests/pipelines/v2_importers/test_suse_score_importer_v2.py b/vulnerabilities/tests/pipelines/v2_importers/test_suse_score_importer_v2.py new file mode 100644 index 000000000..f98bbcc24 --- /dev/null +++ b/vulnerabilities/tests/pipelines/v2_importers/test_suse_score_importer_v2.py @@ -0,0 +1,33 @@ +# +# Copyright (c) nexB Inc. and others. All rights reserved. +# VulnerableCode is a trademark of nexB Inc. +# SPDX-License-Identifier: Apache-2.0 +# See http://www.apache.org/licenses/LICENSE-2.0 for the license text. +# See https://github.com/aboutcode-org/vulnerablecode for support or download. +# See https://aboutcode.org for more information about nexB OSS projects. +# + +from pathlib import Path + +import saneyaml + +from vulnerabilities.pipelines.v2_importers.suse_score_importer import ( + SUSESeverityScoreImporterPipeline, +) +from vulnerabilities.tests import util_tests + +TEST_DATA = Path(__file__).parent.parent.parent / "test_data" / "suse_scores_v2" + +TEST_YAML_DB = TEST_DATA / "suse-cvss-scores.yaml" + + +def test_suse_score_advisories(): + pipeline = SUSESeverityScoreImporterPipeline() + + with open(TEST_YAML_DB) as f: + pipeline.score_data = saneyaml.load(f) + + result = [adv.to_dict() for adv in pipeline.collect_advisories()] + + expected_file = TEST_DATA / "suse-cvss-scores-expected.json" + util_tests.check_results_against_json(result, expected_file) diff --git a/vulnerabilities/tests/test_data/suse_scores_v2/suse-cvss-scores-expected.json b/vulnerabilities/tests/test_data/suse_scores_v2/suse-cvss-scores-expected.json new file mode 100644 index 000000000..a68ace5b9 --- /dev/null +++ b/vulnerabilities/tests/test_data/suse_scores_v2/suse-cvss-scores-expected.json @@ -0,0 +1,84 @@ +[ + { + "advisory_id": "CVE-2004-0230", + "aliases": [], + "summary": "", + "affected_packages": [], + "references_v2": [ + { + "reference_id": "CVE-2004-0230", + "reference_type": "", + "url": "https://ftp.suse.com/pub/projects/security/yaml/suse-cvss-scores.yaml" + } + ], + "patches": [], + "severities": [ + { + "system": "cvssv2", + "value": "4.3", + "scoring_elements": "AV:N/AC:M/Au:N/C:N/I:N/A:P" + }, + { + "system": "cvssv3.1", + "value": "3.7", + "scoring_elements": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L" + } + ], + "date_published": null, + "weaknesses": [], + "url": "https://ftp.suse.com/pub/projects/security/yaml/suse-cvss-scores.yaml" + }, + { + "advisory_id": "CVE-2003-1605", + "aliases": [], + "summary": "", + "affected_packages": [], + "references_v2": [ + { + "reference_id": "CVE-2003-1605", + "reference_type": "", + "url": "https://ftp.suse.com/pub/projects/security/yaml/suse-cvss-scores.yaml" + } + ], + "patches": [], + "severities": [ + { + "system": "cvssv3", + "value": "8.6", + "scoring_elements": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N" + } + ], + "date_published": null, + "weaknesses": [], + "url": "https://ftp.suse.com/pub/projects/security/yaml/suse-cvss-scores.yaml" + }, + { + "advisory_id": "CVE-2010-20103", + "aliases": [], + "summary": "", + "affected_packages": [], + "references_v2": [ + { + "reference_id": "CVE-2010-20103", + "reference_type": "", + "url": "https://ftp.suse.com/pub/projects/security/yaml/suse-cvss-scores.yaml" + } + ], + "patches": [], + "severities": [ + { + "system": "cvssv3.1", + "value": "9.8", + "scoring_elements": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H" + }, + { + "system": "cvssv4", + "value": "9.3", + "scoring_elements": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N" + } + ], + "date_published": null, + "weaknesses": [], + "url": "https://ftp.suse.com/pub/projects/security/yaml/suse-cvss-scores.yaml" + } +] \ No newline at end of file diff --git a/vulnerabilities/tests/test_data/suse_scores_v2/suse-cvss-scores.yaml b/vulnerabilities/tests/test_data/suse_scores_v2/suse-cvss-scores.yaml new file mode 100644 index 000000000..c03bb8780 --- /dev/null +++ b/vulnerabilities/tests/test_data/suse_scores_v2/suse-cvss-scores.yaml @@ -0,0 +1,22 @@ +--- +CVE-2004-0230: + cvss: + - version: 2.0 + score: 4.3 + vector: AV:N/AC:M/Au:N/C:N/I:N/A:P + - version: 3.1 + score: 3.7 + vector: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L +CVE-2003-1605: + cvss: + - version: 3 + score: 8.6 + vector: CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N +CVE-2010-20103: + cvss: + - version: 3.1 + score: 9.8 + vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H + - version: 4 + score: 9.3 + vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N \ No newline at end of file