diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 84ac0ba0e..68f5c1a00 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -9,6 +9,7 @@ Next release - We re-enabled support for the gentoo vulnerabilities advisories importer. - We re-enabled support for the istio vulnerabilities advisories importer. - We re-enabled support for the kbmsr2019 vulnerabilities advisories importer. +- We re-enabled support for the suse score advisories importer. Version v31.1.1 diff --git a/vulnerabilities/importers/__init__.py b/vulnerabilities/importers/__init__.py index b5c955177..1095739bd 100644 --- a/vulnerabilities/importers/__init__.py +++ b/vulnerabilities/importers/__init__.py @@ -27,6 +27,7 @@ from vulnerabilities.importers import pysec from vulnerabilities.importers import redhat from vulnerabilities.importers import retiredotnet +from vulnerabilities.importers import suse_scores from vulnerabilities.importers import ubuntu IMPORTERS_REGISTRY = [ @@ -51,6 +52,7 @@ gentoo.GentooImporter, istio.IstioImporter, project_kb_msr2019.ProjectKBMSRImporter, + suse_scores.SUSESeverityScoreImporter, ] IMPORTERS_REGISTRY = {x.qualified_name: x for x in IMPORTERS_REGISTRY} diff --git a/vulnerabilities/importers/suse_scores.py b/vulnerabilities/importers/suse_scores.py index 16428035f..1a9f4c03a 100644 --- a/vulnerabilities/importers/suse_scores.py +++ b/vulnerabilities/importers/suse_scores.py @@ -7,39 +7,44 @@ # 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 Importer from vulnerabilities.importer import Reference from vulnerabilities.importer import VulnerabilitySeverity from vulnerabilities.utils import fetch_yaml +from vulnerabilities.utils import is_cve URL = "https://ftp.suse.com/pub/projects/security/yaml/suse-cvss-scores.yaml" class SUSESeverityScoreImporter(Importer): - def updated_advisories(self): - advisories = [] + + spdx_license_expression = "CC-BY-4.0" + license_url = "https://ftp.suse.com/pub/projects/security/yaml/LICENSE" + + def advisory_data(self) -> Iterable[AdvisoryData]: score_data = fetch_yaml(URL) - advisories.append(self.to_advisory(score_data)) - return advisories + yield from self.to_advisory(score_data) - @staticmethod - def to_advisory(score_data): + def to_advisory(self, score_data): systems_by_version = { "2.0": severity_systems.CVSSV2, "3": severity_systems.CVSSV3, "3.1": severity_systems.CVSSV31, } - advisories = [] - for cve_id in score_data: + for cve_id in score_data or []: severities = [] - for cvss_score in score_data[cve_id]["cvss"]: - cvss_version = cvss_score["version"] - scoring_system = systems_by_version[cvss_version] - base_score = str(cvss_score["score"]) - vector = str(cvss_score.get("vector", "")) + for cvss_score in 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: + continue + base_score = str(cvss_score.get("score") or "") + vector = str(cvss_score.get("vector") or "") score = VulnerabilitySeverity( system=scoring_system, value=base_score, @@ -47,11 +52,11 @@ def to_advisory(score_data): ) severities.append(score) - advisories.append( - AdvisoryData( - vulnerability_id=cve_id, - summary="", - references=[Reference(url=URL, severities=severities)], - ) + if not is_cve(cve_id): + continue + + yield AdvisoryData( + aliases=[cve_id], + summary="", + references=[Reference(url=URL, severities=severities)], ) - return advisories diff --git a/vulnerabilities/tests/conftest.py b/vulnerabilities/tests/conftest.py index 67cb8492e..9d9764694 100644 --- a/vulnerabilities/tests/conftest.py +++ b/vulnerabilities/tests/conftest.py @@ -36,7 +36,6 @@ def no_rmtree(monkeypatch): "test_safety_db.py", "test_suse_backports.py", "test_suse.py", - "test_suse_scores.py", "test_ubuntu_usn.py", "test_upstream.py", ] diff --git a/vulnerabilities/tests/test_data/suse_scores/suse-cvss-scores-expected.json b/vulnerabilities/tests/test_data/suse_scores/suse-cvss-scores-expected.json new file mode 100644 index 000000000..4f59d6dad --- /dev/null +++ b/vulnerabilities/tests/test_data/suse_scores/suse-cvss-scores-expected.json @@ -0,0 +1,49 @@ +[ + { + "aliases": [ + "CVE-2004-0230" + ], + "summary": "", + "affected_packages": [], + "references": [ + { + "reference_id": "", + "url": "https://ftp.suse.com/pub/projects/security/yaml/suse-cvss-scores.yaml", + "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 + }, + { + "aliases": [ + "CVE-2003-1605" + ], + "summary": "", + "affected_packages": [], + "references": [ + { + "reference_id": "", + "url": "https://ftp.suse.com/pub/projects/security/yaml/suse-cvss-scores.yaml", + "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 + } +] \ No newline at end of file diff --git a/vulnerabilities/tests/test_suse_scores.py b/vulnerabilities/tests/test_suse_scores.py index 4f6b39a8a..0abdd48b1 100644 --- a/vulnerabilities/tests/test_suse_scores.py +++ b/vulnerabilities/tests/test_suse_scores.py @@ -8,65 +8,18 @@ # import os -from unittest import TestCase -from vulnerabilities import severity_systems -from vulnerabilities.importer import AdvisoryData -from vulnerabilities.importer import Reference -from vulnerabilities.importer import VulnerabilitySeverity from vulnerabilities.importers.suse_scores import SUSESeverityScoreImporter +from vulnerabilities.tests import util_tests from vulnerabilities.utils import load_yaml BASE_DIR = os.path.dirname(os.path.abspath(__file__)) -TEST_DATA = os.path.join(BASE_DIR, "test_data/suse_scores", "suse-cvss-scores.yaml") +TEST_DIR = os.path.join(BASE_DIR, "test_data/suse_scores") -class TestSUSESeverityScoreImporter(TestCase): - def test_to_advisory(self): - raw_data = load_yaml(TEST_DATA) - expected_data = [ - AdvisoryData( - summary="", - references=[ - Reference( - reference_id="", - url="https://ftp.suse.com/pub/projects/security/yaml/suse-cvss-scores.yaml", - severities=[ - VulnerabilitySeverity( - system=severity_systems.CVSSV2, - value="4.3", - scoring_elements="AV:N/AC:M/Au:N/C:N/I:N/A:P", - ), - VulnerabilitySeverity( - system=severity_systems.CVSSV31, - value="3.7", - scoring_elements="CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L", - ), - ], - ) - ], - vulnerability_id="CVE-2004-0230", - ), - AdvisoryData( - summary="", - references=[ - Reference( - reference_id="", - url="https://ftp.suse.com/pub/projects/security/yaml/suse-cvss-scores.yaml", - severities=[ - VulnerabilitySeverity( - system=severity_systems.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", - ), - ], - ) - ], - vulnerability_id="CVE-2003-1605", - ), - ] - - found_data = SUSESeverityScoreImporter.to_advisory(raw_data) - found_advisories = list(map(AdvisoryData.normalized, found_data)) - expected_advisories = list(map(AdvisoryData.normalized, expected_data)) - assert sorted(found_advisories) == sorted(expected_advisories) +def test_suse_score_import(): + raw_data = load_yaml(os.path.join(TEST_DIR, "suse-cvss-scores.yaml")) + expected_file = os.path.join(TEST_DIR, "suse-cvss-scores-expected.json") + advisories = list(SUSESeverityScoreImporter().to_advisory(raw_data)) + expected_advisories = [adv.to_dict() for adv in advisories] + util_tests.check_results_against_json(expected_advisories, expected_file)