def extract_severity_scores(cve_item): severity_scores = [] if cve_item["impact"].get("baseMetricV3"): severity_scores.append( VulnerabilitySeverity( system=scoring_systems["cvssv3"], value=str(cve_item["impact"]["baseMetricV3"]["cvssV3"]["baseScore"]), ) ) severity_scores.append( VulnerabilitySeverity( system=scoring_systems["cvssv3_vector"], value=str(cve_item["impact"]["baseMetricV3"]["cvssV3"]["vectorString"]), ) ) if cve_item["impact"].get("baseMetricV2"): severity_scores.append( VulnerabilitySeverity( system=scoring_systems["cvssv2"], value=str(cve_item["impact"]["baseMetricV2"]["cvssV2"]["baseScore"]), ) ) severity_scores.append( VulnerabilitySeverity( system=scoring_systems["cvssv2_vector"], value=str(cve_item["impact"]["baseMetricV2"]["cvssV2"]["vectorString"]), ) ) return severity_scores
def test_to_advisories(self): expected_advisories = [ Advisory( summary=( "Multiple integer overflows in TCMalloc (tcmalloc.cc) in gperftools " "before 0.4 make it easier for context-dependent attackers to perform memory-related " # nopep8 "attacks such as buffer overflows via a large size value, which causes less memory to " # nopep8 "be allocated than expected." ), impacted_package_urls=[], resolved_package_urls=[], vuln_references=sorted( [ Reference( url="http://code.google.com/p/gperftools/source/browse/tags/perftools-0.4/ChangeLog", # nopep8 ), Reference( url="http://kqueue.org/blog/2012/03/05/memory-allocator-security-revisited/", # nopep8 ), Reference( url="https://nvd.nist.gov/vuln/detail/CVE-2005-4895", severities=[ VulnerabilitySeverity( system=scoring_systems["cvssv2"], value="5.0", ), VulnerabilitySeverity( system=scoring_systems["cvssv2_vector"], value="AV:N/AC:L/Au:N/C:N/I:N/A:P", ), ], reference_id="CVE-2005-4895", ), ], key=lambda x: x.url, ), vulnerability_id="CVE-2005-4895", ) ] assert len(self.nvd_data["CVE_Items"]) == 2 found_advisories = list(self.data_src.to_advisories(self.nvd_data)) # Only 1 advisory because other advisory is hardware related assert len(found_advisories) == 1 found_advisories[0].vuln_references = sorted( found_advisories[0].vuln_references, key=lambda x: x.url ) # nopep8 assert expected_advisories == found_advisories
def _parse(self, record) -> List[Advisory]: advisories = [] for cve_id in record["issues"]: affected_packages = [] for name in record["packages"]: impacted_purls, resolved_purls = [], [] impacted_purls.append( PackageURL( name=name, type="pacman", namespace="archlinux", version=record["affected"], ) ) if record["fixed"]: resolved_purls.append( PackageURL( name=name, type="pacman", namespace="archlinux", version=record["fixed"], ) ) affected_packages.extend(nearest_patched_package(impacted_purls, resolved_purls)) references = [] references.append( Reference( reference_id=record["name"], url="https://security.archlinux.org/{}".format(record["name"]), severities=[ VulnerabilitySeverity( system=scoring_systems["avgs"], value=record["severity"] ) ], ) ) for ref in record["advisories"]: references.append( Reference( reference_id=ref, url="https://security.archlinux.org/{}".format(ref), ) ) advisories.append( Advisory( vulnerability_id=cve_id, summary="", affected_packages=affected_packages, references=references, ) ) return advisories
def test_to_advisory(self): expected_advisories = [ Advisory( summary= "A serious problem exists when a client sends a large number of " "headers with the same header name. Apache uses up memory faster than the " "amount of memory required to simply store the received data itself. That " "is, memory use increases faster and faster as more headers are received, " "rather than increasing at a constant rate. This makes a denial of service " "attack based on this method more effective than methods which cause Apache" " to use memory at a constant rate, since the attacker has to send less data.", affected_packages=[ AffectedPackage(vulnerable_package=PackageURL( type="apache", name="httpd", version="1.3.0", ), ), AffectedPackage(vulnerable_package=PackageURL( type="apache", name="httpd", version="1.3.1", ), ), ], references=[ Reference( url= "https://httpd.apache.org/security/json/CVE-1999-1199.json", severities=[ VulnerabilitySeverity( system=scoring_systems["apache_httpd"], value="important", ), ], reference_id="CVE-1999-1199", ), ], vulnerability_id="CVE-1999-1199", ) ] found_advisories = [self.data_src.to_advisory(self.data)] found_advisories = list(map(Advisory.normalized, found_advisories)) expected_advisories = list( map(Advisory.normalized, expected_advisories)) assert sorted(found_advisories) == sorted(expected_advisories)
def to_advisory(score_data): advisories = [] for cve_id in score_data: severities = [] for cvss_score in score_data[cve_id]["cvss"]: score = None vector = None if cvss_score["version"] == 2.0: score = VulnerabilitySeverity( system=scoring_systems["cvssv2"], value=str(cvss_score["score"])) vector = VulnerabilitySeverity( system=scoring_systems["cvssv2_vector"], value=str(cvss_score["vector"])) elif cvss_score["version"] == 3: score = VulnerabilitySeverity( system=scoring_systems["cvssv3"], value=str(cvss_score["score"])) vector = VulnerabilitySeverity( system=scoring_systems["cvssv3_vector"], value=str(cvss_score["vector"])) elif cvss_score["version"] == 3.1: score = VulnerabilitySeverity( system=scoring_systems["cvssv3.1"], value=str(cvss_score["score"])) vector = VulnerabilitySeverity( system=scoring_systems["cvssv3.1_vector"], value=str(cvss_score["vector"])) severities.extend([score, vector]) advisories.append( Advisory(vulnerability_id=cve_id, summary="", impacted_package_urls=[], vuln_references=[ Reference(url=URL, severities=severities) ])) return advisories
def test_to_advisory(self): data = load_test_data() expected_data = { Advisory( summary="CVE-2016-9401 bash: popd controlled free", impacted_package_urls=[ PackageURL( type="rpm", namespace="redhat", name="bash", version="4.2.46-28.el7", qualifiers={}, subpath=None, ), PackageURL( type="rpm", namespace="redhat", name="bash", version="4.1.2-48.el6", qualifiers={}, subpath=None, ), ], resolved_package_urls=[], vuln_references=[ Reference( reference_id="RHSA-2017:0725", url="https://access.redhat.com/errata/RHSA-2017:0725", severities=[ VulnerabilitySeverity( system=scoring_systems["rhas"], value=2.2, ) ], ), Reference( reference_id="RHSA-2017:1931", url="https://access.redhat.com/errata/RHSA-2017:1931", severities=[ VulnerabilitySeverity( system=scoring_systems["rhas"], value=2.2, ) ], ), Reference( reference_id="", url="https://access.redhat.com/hydra/rest/securitydata/cve/CVE-2016-9401.json", # nopep8 severities=[ VulnerabilitySeverity( system=scoring_systems["cvssv3"], value="3.3", ), VulnerabilitySeverity( system=scoring_systems["cvssv3_vector"], value="CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L", ), ], ), Reference( reference_id="1396383", url="https://bugzilla.redhat.com/show_bug.cgi?id=1396383", severities=[ VulnerabilitySeverity( system=scoring_systems["rhbs"], value=2.0, ) ], ), ], vulnerability_id="CVE-2016-9401", ) } found_data = set() mock_resp = unittest.mock.MagicMock() mock_resp.json = lambda: { "bugs": [{"severity": 2.0}], "cvrfdoc": {"aggregate_severity": 2.2}, } for adv in data: with unittest.mock.patch( "vulnerabilities.importers.redhat.requests.get", return_value=mock_resp ): adv = redhat.to_advisory(adv) adv.vuln_references = sorted(adv.vuln_references, key=lambda x: x.url) found_data.add(adv) assert expected_data == found_data
def to_advisory(advisory_data): affected_purls = [] if advisory_data.get("affected_packages"): for rpm in advisory_data["affected_packages"]: purl = rpm_to_purl(rpm) if purl: affected_purls.append(purl) references = [] bugzilla = advisory_data.get("bugzilla") if bugzilla: url = "https://bugzilla.redhat.com/show_bug.cgi?id={}".format(bugzilla) bugzilla_data = requests_session.get( f"https://bugzilla.redhat.com/rest/bug/{bugzilla}" ).json() if ( bugzilla_data.get("bugs") and len(bugzilla_data["bugs"]) and bugzilla_data["bugs"][0].get("severity") ): bugzilla_severity_val = bugzilla_data["bugs"][0]["severity"] bugzilla_severity = VulnerabilitySeverity( system=scoring_systems["rhbs"], value=bugzilla_severity_val, ) references.append( Reference( severities=[bugzilla_severity], url=url, reference_id=bugzilla, ) ) for rh_adv in advisory_data["advisories"]: # RH provides 3 types of advisories RHSA, RHBA, RHEA. Only RHSA's contain severity score. # See https://access.redhat.com/articles/2130961 for more details. if "RHSA" in rh_adv.upper(): rhsa_data = requests_session.get( f"https://access.redhat.com/hydra/rest/securitydata/cvrf/{rh_adv}.json" ).json() # nopep8 rhsa_aggregate_severities = [] if rhsa_data.get("cvrfdoc"): # not all RHSA errata have a corresponding CVRF document value = rhsa_data["cvrfdoc"]["aggregate_severity"] rhsa_aggregate_severities.append( VulnerabilitySeverity( system=scoring_systems["rhas"], value=value, ) ) references.append( Reference( severities=rhsa_aggregate_severities, url="https://access.redhat.com/errata/{}".format(rh_adv), reference_id=rh_adv, ) ) else: references.append(Reference(severities=[], url=url, reference_id=rh_adv)) redhat_scores = [] cvssv3_score = advisory_data.get("cvss3_score") if cvssv3_score: redhat_scores.append( VulnerabilitySeverity( system=scoring_systems["cvssv3"], value=cvssv3_score, ) ) cvssv3_vector = advisory_data.get("cvss3_scoring_vector") if cvssv3_vector: redhat_scores.append( VulnerabilitySeverity( system=scoring_systems["cvssv3_vector"], value=cvssv3_vector, ) ) references.append(Reference(severities=redhat_scores, url=advisory_data["resource_url"])) return Advisory( vulnerability_id=advisory_data["CVE"], summary=advisory_data["bugzilla_description"], impacted_package_urls=affected_purls, references=references, )
def test_process_response(self): with open(os.path.join(TEST_DATA, "github_api", "response.json")) as f: resp = json.load(f) self.data_src.advisories = resp expected_result = [ Advisory( summary="Denial of Service in Tomcat", impacted_package_urls=set(), resolved_package_urls={ PackageURL( type="maven", namespace="org.apache.tomcat.embed", name="tomcat-embed-core", version="9.0.2", qualifiers={}, subpath=None, ), PackageURL( type="maven", namespace="org.apache.tomcat.embed", name="tomcat-embed-core", version="1.2.0", qualifiers={}, subpath=None, ), }, vuln_references=[ Reference( reference_id="GHSA-qcxh-w3j9-58qr", url="https://github.com/advisories/GHSA-qcxh-w3j9-58qr", severities=[ VulnerabilitySeverity( system=ScoringSystem( identifier="cvssv3.1_qr", name="CVSSv3.1 Qualitative Severity Rating", url= "https://www.first.org/cvss/specification-document", notes= "A textual interpretation of severity. Has values like HIGH, MODERATE etc", # nopep8 ), value="MODERATE", ) ], ) ], vulnerability_id="CVE-2019-0199", ), Advisory( summary="Denial of Service in Tomcat", impacted_package_urls={ PackageURL( type="maven", namespace="org.apache.tomcat.embed", name="tomcat-embed-core", version="9.0.2", qualifiers={}, subpath=None, ) }, resolved_package_urls={ PackageURL( type="maven", namespace="org.apache.tomcat.embed", name="tomcat-embed-core", version="1.2.0", qualifiers={}, subpath=None, ) }, vuln_references=[ Reference( reference_id="GHSA-qcxh-w3j9-58qr", url="https://github.com/advisories/GHSA-qcxh-w3j9-58qr", severities=[ VulnerabilitySeverity( system=ScoringSystem( identifier="cvssv3.1_qr", name="CVSSv3.1 Qualitative Severity Rating", url= "https://www.first.org/cvss/specification-document", notes= "A textual interpretation of severity. Has values like HIGH, MODERATE etc", # nopep8 ), value="HIGH", ) ], ) ], vulnerability_id="CVE-2019-0199", ), Advisory( summary="Improper Input Validation in Tomcat", impacted_package_urls=set(), resolved_package_urls={ PackageURL( type="maven", namespace="org.apache.tomcat.embed", name="tomcat-embed-core", version="9.0.2", qualifiers={}, subpath=None, ), PackageURL( type="maven", namespace="org.apache.tomcat.embed", name="tomcat-embed-core", version="1.2.0", qualifiers={}, subpath=None, ), }, vuln_references=[ Reference( reference_id="GHSA-c9hw-wf7x-jp9j", url="https://github.com/advisories/GHSA-c9hw-wf7x-jp9j", severities=[ VulnerabilitySeverity( system=ScoringSystem( identifier="cvssv3.1_qr", name="CVSSv3.1 Qualitative Severity Rating", url= "https://www.first.org/cvss/specification-document", notes= "A textual interpretation of severity. Has values like HIGH, MODERATE etc", # nopep8 ), value="LOW", ) ], ) ], vulnerability_id="CVE-2020-1938", ), Advisory( summary="Improper Input Validation in Tomcat", impacted_package_urls=set(), resolved_package_urls={ PackageURL( type="maven", namespace="org.apache.tomcat.embed", name="tomcat-embed-core", version="9.0.2", qualifiers={}, subpath=None, ), PackageURL( type="maven", namespace="org.apache.tomcat.embed", name="tomcat-embed-core", version="1.2.0", qualifiers={}, subpath=None, ), }, vuln_references=[ Reference( reference_id="GHSA-c9hw-wf7x-jp9j", url="https://github.com/advisories/GHSA-c9hw-wf7x-jp9j", severities=[ VulnerabilitySeverity( system=ScoringSystem( identifier="cvssv3.1_qr", name="CVSSv3.1 Qualitative Severity Rating", url= "https://www.first.org/cvss/specification-document", notes= "A textual interpretation of severity. Has values like HIGH, MODERATE etc", # nopep8 ), value="MODERATE", ) ], ) ], vulnerability_id="CVE-2020-1938", ), Advisory( summary="Improper Input Validation in Tomcat", impacted_package_urls={ PackageURL( type="maven", namespace="org.apache.tomcat.embed", name="tomcat-embed-core", version="9.0.2", qualifiers={}, subpath=None, ) }, resolved_package_urls={ PackageURL( type="maven", namespace="org.apache.tomcat.embed", name="tomcat-embed-core", version="1.2.0", qualifiers={}, subpath=None, ) }, vuln_references=[ Reference( reference_id="GHSA-c9hw-wf7x-jp9j", url="https://github.com/advisories/GHSA-c9hw-wf7x-jp9j", severities=[ VulnerabilitySeverity( system=ScoringSystem( identifier="cvssv3.1_qr", name="CVSSv3.1 Qualitative Severity Rating", url= "https://www.first.org/cvss/specification-document", notes= "A textual interpretation of severity. Has values like HIGH, MODERATE etc", # nopep8 ), value="LOW", ) ], ) ], vulnerability_id="CVE-2020-1938", ), ] mock_version_api = MagicMock() mock_version_api.package_type = "maven" mock_version_api.get = lambda x: {"1.2.0", "9.0.2"} with patch("vulnerabilities.importers.github.MavenVersionAPI", return_value=mock_version_api): # nopep8 with patch( "vulnerabilities.importers.github.GitHubAPIDataSource.set_api" ): found_result = self.data_src.process_response() assert expected_result == found_result
def test_to_advisory(self): raw_data = load_yaml(TEST_DATA) expected_data = [ Advisory( summary="", references=[ Reference( reference_id="", url= "https://ftp.suse.com/pub/projects/security/yaml/suse-cvss-scores.yaml", severities=[ VulnerabilitySeverity( system=ScoringSystem( identifier="cvssv2", name="CVSSv2 Base Score", url="https://www.first.org/cvss/v2/", notes="cvssv2 base score", ), value="4.3", ), VulnerabilitySeverity( system=ScoringSystem( identifier="cvssv2_vector", name="CVSSv2 Vector", url="https://www.first.org/cvss/v2/", notes= "cvssv2 vector, used to get additional info about nature and severity of vulnerability", # nopep8 ), value="AV:N/AC:M/Au:N/C:N/I:N/A:P", ), VulnerabilitySeverity( system=ScoringSystem( identifier="cvssv3.1", name="CVSSv3.1 Base Score", url="https://www.first.org/cvss/v3-1/", notes="cvssv3.1 base score", ), value="3.7", ), VulnerabilitySeverity( system=ScoringSystem( identifier="cvssv3.1_vector", name="CVSSv3.1 Vector", url="https://www.first.org/cvss/v3-1/", notes= "cvssv3.1 vector, used to get additional info about nature and severity of vulnerability", # nopep8 ), value= "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L", ), ], ) ], vulnerability_id="CVE-2004-0230", ), Advisory( summary="", references=[ Reference( reference_id="", url= "https://ftp.suse.com/pub/projects/security/yaml/suse-cvss-scores.yaml", severities=[ VulnerabilitySeverity( system=ScoringSystem( identifier="cvssv3", name="CVSSv3 Base Score", url="https://www.first.org/cvss/v3-0/", notes="cvssv3 base score", ), value="8.6", ), VulnerabilitySeverity( system=ScoringSystem( identifier="cvssv3_vector", name="CVSSv3 Vector", url="https://www.first.org/cvss/v3-0/", notes= "cvssv3 vector, used to get additional info about nature and severity of vulnerability", # nopep8 ), value= "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 = SUSESeverityScoreDataSource.to_advisory(raw_data) found_advisories = list(map(Advisory.normalized, found_data)) expected_advisories = list(map(Advisory.normalized, expected_data)) assert sorted(found_advisories) == sorted(expected_advisories)
def to_advisory(self, data): cve = data["CVE_data_meta"]["ID"] descriptions = data["description"]["description_data"] description = None for desc in descriptions: if desc["lang"] == "eng": description = desc.get("value") break severities = [] impacts = data.get("impact", []) for impact in impacts: value = impact.get("other") if value: severities.append( VulnerabilitySeverity( system=scoring_systems["apache_httpd"], value=value, ) ) break reference = Reference( reference_id=cve, url=urllib.parse.urljoin(self.base_url, f"{cve}.json"), severities=severities, ) versions_data = [] for vendor in data["affects"]["vendor"]["vendor_data"]: for products in vendor["product"]["product_data"]: for version_data in products["version"]["version_data"]: versions_data.append(version_data) fixed_version_ranges, affected_version_ranges = self.to_version_ranges(versions_data) affected_packages = [] fixed_packages = [] for version_range in fixed_version_ranges: fixed_packages.extend( [ PackageURL(type="apache", name="httpd", version=version) for version in self.version_api.get("apache/httpd") if MavenVersion(version) in version_range ] ) for version_range in affected_version_ranges: affected_packages.extend( [ PackageURL(type="apache", name="httpd", version=version) for version in self.version_api.get("apache/httpd") if MavenVersion(version) in version_range ] ) return Advisory( vulnerability_id=cve, summary=description, affected_packages=nearest_patched_package(affected_packages, fixed_packages), references=[reference], )
def test_to_advisory(self): data = load_test_data() expected_advisories = [ Advisory( summary="CVE-2016-9401 bash: popd controlled free", vulnerability_id="CVE-2016-9401", affected_packages=[ AffectedPackage( vulnerable_package=PackageURL( type="rpm", namespace="redhat", name="bash", version="4.1.2-48.el6", ), patched_package=None, ), AffectedPackage( vulnerable_package=PackageURL( type="rpm", namespace="redhat", name="bash", version="4.2.46-28.el7", ), patched_package=None, ), ], references=[ Reference( reference_id="", url="https://access.redhat.com/hydra/rest/securitydata/cve/CVE-2016-9401.json", severities=[ VulnerabilitySeverity( system=ScoringSystem( identifier="cvssv3", name="CVSSv3 Base Score", url="https://www.first.org/cvss/v3-0/", notes="cvssv3 base score", ), value="3.3", ), VulnerabilitySeverity( system=ScoringSystem( identifier="cvssv3_vector", name="CVSSv3 Vector", url="https://www.first.org/cvss/v3-0/", notes="cvssv3 vector, used to get additional info about nature and severity of vulnerability", ), value="CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L", ), ], ), Reference( reference_id="1396383", url="https://bugzilla.redhat.com/show_bug.cgi?id=1396383", severities=[ VulnerabilitySeverity( system=ScoringSystem( identifier="rhbs", name="RedHat Bugzilla severity", url="https://bugzilla.redhat.com/page.cgi?id=fields.html#bug_severity", notes="", ), value=2.0, ) ], ), Reference( reference_id="RHSA-2017:0725", url="https://access.redhat.com/errata/RHSA-2017:0725", severities=[ VulnerabilitySeverity( system=ScoringSystem( identifier="rhas", name="RedHat Aggregate severity", url="https://access.redhat.com/security/updates/classification/", notes="", ), value=2.2, ) ], ), Reference( reference_id="RHSA-2017:1931", url="https://access.redhat.com/errata/RHSA-2017:1931", severities=[ VulnerabilitySeverity( system=ScoringSystem( identifier="rhas", name="RedHat Aggregate severity", url="https://access.redhat.com/security/updates/classification/", notes="", ), value=2.2, ) ], ), ], ) ] found_advisories = [] mock_resp = unittest.mock.MagicMock() mock_resp.json = lambda: { "bugs": [{"severity": 2.0}], "cvrfdoc": {"aggregate_severity": 2.2}, } for adv in data: with unittest.mock.patch( "vulnerabilities.importers.redhat.requests_session.get", return_value=mock_resp ): adv = redhat.to_advisory(adv) found_advisories.append(adv) found_advisories = list(map(Advisory.normalized, found_advisories)) expected_advisories = list(map(Advisory.normalized, expected_advisories)) assert sorted(found_advisories) == sorted(expected_advisories)
def process_response(self) -> List[Advisory]: adv_list = [] for ecosystem in self.advisories: self.set_version_api(ecosystem) pkg_type = self.version_api.package_type for resp_page in self.advisories[ecosystem]: for adv in resp_page["data"]["securityVulnerabilities"]["edges"]: name = adv["node"]["package"]["name"] if self.process_name(ecosystem, name): ns, pkg_name = self.process_name(ecosystem, name) aff_range = adv["node"]["vulnerableVersionRange"] aff_vers, unaff_vers = self.categorize_versions( aff_range, self.version_api.get(name) ) affected_purls = { PackageURL(name=pkg_name, namespace=ns, version=version, type=pkg_type) for version in aff_vers } unaffected_purls = { PackageURL(name=pkg_name, namespace=ns, version=version, type=pkg_type) for version in unaff_vers } else: affected_purls = set() unaffected_purls = set() cve_ids = set() references = self.extract_references(adv["node"]["advisory"]["references"]) vuln_desc = adv["node"]["advisory"]["summary"] for identifier in adv["node"]["advisory"]["identifiers"]: # collect CVEs if identifier["type"] == "CVE": cve_ids.add(identifier["value"]) # attach the GHSA with severity score if identifier["type"] == "GHSA": for ref in references: if ref.reference_id == identifier["value"]: ref.severities = [ VulnerabilitySeverity( system=scoring_systems["cvssv3.1_qr"], value=adv["node"]["advisory"]["severity"], ) ] # Each Node has only one GHSA, hence exit after attaching # score to this GHSA break for cve_id in cve_ids: adv_list.append( Advisory( vulnerability_id=cve_id, summary=vuln_desc, impacted_package_urls=affected_purls, resolved_package_urls=unaffected_purls, references=references, ) ) return adv_list
def test_to_advisories(self): with open(TEST_DATA) as f: raw_data = f.read() expected_advisories = [ Advisory( summary= "ALTER ... DEPENDS ON EXTENSION is missing authorization checks.more details", vulnerability_id="CVE-2020-1720", affected_packages=[ AffectedPackage( vulnerable_package=PackageURL( type="generic", name="postgresql", version="10", ), patched_package=PackageURL( type="generic", name="postgresql", version="10.12", ), ), AffectedPackage( vulnerable_package=PackageURL( type="generic", name="postgresql", version="11", ), patched_package=PackageURL( type="generic", name="postgresql", version="11.7", ), ), AffectedPackage( vulnerable_package=PackageURL( type="generic", name="postgresql", version="12", ), patched_package=PackageURL( type="generic", name="postgresql", version="12.2", ), ), AffectedPackage( vulnerable_package=PackageURL( type="generic", name="postgresql", version="9.6", ), patched_package=PackageURL( type="generic", name="postgresql", version="9.6.17", ), ), ], references=[ Reference( reference_id="", url= "https://www.postgresql.org/about/news/postgresql-122-117-1012-9617-9521-and-9426-released-2011/", ), Reference( reference_id="", url= "https://www.postgresql.org/support/security/CVE-2020-1720/", severities=[ VulnerabilitySeverity( system=ScoringSystem( identifier="cvssv3", name="CVSSv3 Base Score", url="https://www.first.org/cvss/v3-0/", notes="cvssv3 base score", ), value="3.1", ), VulnerabilitySeverity( system=ScoringSystem( identifier="cvssv3_vector", name="CVSSv3 Vector", url="https://www.first.org/cvss/v3-0/", notes= "cvssv3 vector, used to get additional info about nature and severity of vulnerability", ), value=["AV:N/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N"], ), ], ), ], ), Advisory( summary= "Windows installer runs executables from uncontrolled directoriesmore details", vulnerability_id="CVE-2020-10733", affected_packages=[ AffectedPackage( vulnerable_package=PackageURL( type="generic", name="postgresql", version="10", qualifiers={"os": "windows"}, ), patched_package=PackageURL( type="generic", name="postgresql", version="10.13", qualifiers={"os": "windows"}, ), ), AffectedPackage( vulnerable_package=PackageURL( type="generic", name="postgresql", version="11", qualifiers={"os": "windows"}, ), patched_package=PackageURL( type="generic", name="postgresql", version="11.8", qualifiers={"os": "windows"}, ), ), AffectedPackage( vulnerable_package=PackageURL( type="generic", name="postgresql", version="12", qualifiers={"os": "windows"}, ), patched_package=PackageURL( type="generic", name="postgresql", version="12.3", qualifiers={"os": "windows"}, ), ), AffectedPackage( vulnerable_package=PackageURL( type="generic", name="postgresql", version="9.6", qualifiers={"os": "windows"}, ), patched_package=PackageURL( type="generic", name="postgresql", version="9.6.18", qualifiers={"os": "windows"}, ), ), ], references=[ Reference( reference_id="", url= "https://www.postgresql.org/about/news/postgresql-123-118-1013-9618-and-9522-released-2038/", ), Reference( reference_id="", url= "https://www.postgresql.org/support/security/CVE-2020-10733/", severities=[ VulnerabilitySeverity( system=ScoringSystem( identifier="cvssv3", name="CVSSv3 Base Score", url="https://www.first.org/cvss/v3-0/", notes="cvssv3 base score", ), value="6.7", ), VulnerabilitySeverity( system=ScoringSystem( identifier="cvssv3_vector", name="CVSSv3 Vector", url="https://www.first.org/cvss/v3-0/", notes= "cvssv3 vector, used to get additional info about nature and severity of vulnerability", ), value=["AV:L/AC:H/PR:L/UI:R/S:U/C:H/I:H/A:H"], ), ], ), ], ), ] found_advisories = to_advisories(raw_data) found_advisories = list(map(Advisory.normalized, found_advisories)) expected_advisories = list( map(Advisory.normalized, expected_advisories)) assert sorted(found_advisories) == sorted(expected_advisories)