diff --git a/vulnerabilities/importers/gsd.py b/vulnerabilities/importers/gsd.py new file mode 100644 index 000000000..50d3aa8f6 --- /dev/null +++ b/vulnerabilities/importers/gsd.py @@ -0,0 +1,222 @@ +# +# 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/nexB/vulnerablecode for support or download. +# See https://aboutcode.org for more information about nexB OSS projects. +# +import json +import logging +from io import BytesIO +from typing import Iterable +from typing import List +from typing import Set +from zipfile import ZipFile + +import dateparser +import requests + +from vulnerabilities.importer import AdvisoryData +from vulnerabilities.importer import Importer +from vulnerabilities.importer import Reference +from vulnerabilities.utils import build_description +from vulnerabilities.utils import dedupe + +logger = logging.getLogger(__name__) + + +class GSDImporter: # TODO inherit from Importer + spdx_license_expression = "CC0-1.0" + license_url = "https://github.com/cloudsecurityalliance/gsd-database/blob/main/LICENSE" + url = "https://codeload.github.com/cloudsecurityalliance/gsd-database/zip/refs/heads/main" + + def advisory_data(self) -> Iterable[AdvisoryData]: + response = requests.get(self.url).content + with ZipFile(BytesIO(response)) as zip_file: + for file_name in zip_file.namelist(): + if file_name == "gsd-database-main/allowlist.json" or not file_name.endswith( + ".json" + ): + continue + + with zip_file.open(file_name) as f: + try: + raw_data = json.load(f) + yield parse_advisory_data(raw_data, file_name) + except Exception as e: + logger.error(f"Invalid GSD advisory data file: {file_name} - {e}") + + +def parse_advisory_data(raw_data, file_name): + """ + Parse a GSD advisory file and return an AdvisoryData. + Each advisory file contains the advisory information in JSON format. + """ + + namespaces = raw_data.get("namespaces") or {} + cve_org = namespaces.get("cve.org") or {} + nvd_nist_gov = namespaces.get("nvd.nist.gov") or {} + + gsd = raw_data.get("GSD") or {} + gsd_id = gsd.get("id") or file_name + gsd_alias = gsd.get("alias") or [] + gsd_description = gsd.get("description") or "" + + gsd_reference_data = gsd.get("") or [] + gsd_references = [Reference(url=ref) for ref in gsd_reference_data] + + details = gsd_description or "".join(get_description(cve_org)) + + aliases_cve_org = get_aliases(cve_org) + aliases_nvd_nist_gov = get_aliases(nvd_nist_gov) + + aliases = [gsd_alias, gsd_id] + aliases_cve_org + aliases_nvd_nist_gov + aliases = [alias for alias in aliases if alias is not None] + + summary = build_description(summary=get_summary(cve_org), description=details) + + severities = get_severities(cve_org) + configurations = nvd_nist_gov.get("configurations") or {} + nodes = configurations.get("nodes") or [] + cpes = get_cpe(nodes) + + references = get_references(cve_org) + gsd_references + + date_published = get_published_date_nvd_nist_gov(nvd_nist_gov) + + return AdvisoryData( + aliases=dedupe(aliases), + summary=summary, + references=references, + date_published=date_published, + ) + + +def get_summary(cve) -> str: + """ + Returns a title of CVE_data_meta + >> get_summary {"CVE_data_meta": {"TITLE": "DoS vulnerability: Invalid Accent Colors"} + 'DoS vulnerability: Invalid Accent Colors' + """ + cve_data_meta = cve.get("CVE_data_meta") or {} + return cve_data_meta.get("TITLE") or "" + + +def get_severities(cve) -> List: + """ + Return a list of CVSS vectorString + >>> get_severities({"impact": {"cvss": {"vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:N/A:H"}}}) + ['CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:N/A:H'] + """ + severities = [] + impact = cve.get("impact") or {} + + base_metric_2 = impact.get("baseMetricV2") or {} + if base_metric_2: + cvss_v2 = base_metric_2.get("cvssV2") or {} + cvss_vector = cvss_v2.get("vectorString") + if cvss_vector: + severities.append(cvss_vector) + + base_metric_v3 = impact.get("baseMetricV3") or {} + if base_metric_v3: + cvss_v3 = base_metric_v3.get("cvssV3") or {} + cvss_vector = cvss_v3.get("vectorString") + if cvss_vector: + severities.append(cvss_vector) + + cvss = impact.get("cvss") or {} + if isinstance(cvss, List): + for cvss_v in cvss: + if isinstance(cvss_v, dict): + cvss_vector = cvss_v.get("vectorString") or {} + if cvss_vector: + severities.append(cvss_vector) + else: + cvss_vector = cvss.get("vectorString") + if cvss_vector: + severities.append(cvss_vector) + return severities + + +def get_description(cve) -> [str]: + """ + Get a list description value from description object + >>> get_description({"description": {"description_data": [{"lang": "eng","value": "the description"}]}}) + ['the description'] + """ + description = cve.get("description") or {} + description_data = description.get("description_data") or [] + return [desc["value"] for desc in description_data if desc["value"] and desc["lang"] == "eng"] + + +def get_references(cve): + """ + Returns a list of Reference assigned with url + >>> get_references({"references": { + ... "reference_data": [{ + ... "name": "https://kc.mcafee.com/corporate/index?page=content&id=SB10198", + ... "refsource": "CONFIRM", + ... "tags": ["Vendor Advisory"], + ... "url": "https://kc.mcafee.com/corporate/index?page=content&id=SB10198"}]}}) + [Reference(reference_id='', reference_type='', url='https://kc.mcafee.com/corporate/index?page=content&id=SB10198', severities=[])] + """ + references = cve.get("references") or {} + reference_data = references.get("reference_data") or [] + return [Reference(url=ref["url"]) for ref in reference_data if ref["url"]] + + +def get_aliases(cve) -> [str]: + """ + Returns a list of aliases + >>> get_aliases({"CVE_data_meta": {"ID": "CVE-2017-4017"},"source": {"advisory": "GHSA-v8x6-59g4-5g3w"}}) + ['CVE-2017-4017', 'GHSA-v8x6-59g4-5g3w'] + """ + cve_data_meta = cve.get("CVE_data_meta") or {} + alias = cve_data_meta.get("ID") + + source = cve.get("source") or {} + advisory = source.get("advisory") + + aliases = [] + if alias: + aliases.append(alias) + if advisory: + aliases.append(advisory) + return aliases + + +def get_published_date_nvd_nist_gov(nvd_nist_gov): + """ + Returns a published datetime + >>> get_published_date_nvd_nist_gov({"publishedDate": "2022-06-23T07:15Z"}) + datetime.datetime(2022, 6, 23, 7, 15, tzinfo=) + """ + published_date = nvd_nist_gov.get("publishedDate") + return published_date and dateparser.parse(published_date) + + +def get_cpe(nodes) -> List: + """ + >>> get_cpe([{"children": [], "cpe_match": [{ + ... "cpe23Uri": "cpe:2.3:a:mutt:mutt:*:*:*:*:*:*:*:*", + ... "cpe_name": [], + ... "versionEndIncluding": "1.2.5.1", + ... "vulnerable": True + ... },{ + ... "cpe23Uri": "cpe:2.3:a:mutt:mutt:*:*:*:*:*:*:*:*", + ... "cpe_name": [], + ... "versionEndIncluding": "1.3.25", + ... "vulnerable": True + ... }],"operator": "OR"}]) + ['cpe:2.3:a:mutt:mutt:*:*:*:*:*:*:*:*', 'cpe:2.3:a:mutt:mutt:*:*:*:*:*:*:*:*'] + """ + cpe_list = [] + for node in nodes: + cpe_match = node.get("cpe_match") or [] + for cpe23Uri in cpe_match: + cpe_uri = cpe23Uri.get("cpe23Uri") + if cpe_uri: + cpe_list.append(cpe_uri) + return cpe_list diff --git a/vulnerabilities/tests/test_data/gsd/GSD-2002-0001-expected.json b/vulnerabilities/tests/test_data/gsd/GSD-2002-0001-expected.json new file mode 100644 index 000000000..60f1c9f31 --- /dev/null +++ b/vulnerabilities/tests/test_data/gsd/GSD-2002-0001-expected.json @@ -0,0 +1,105 @@ +{ + "aliases": [ + "CVE-2002-0001", + "GSD-2002-0001" + ], + "summary": "Vulnerability in RFC822 address parser in mutt before 1.2.5.1 and mutt 1.3.x before 1.3.25 allows remote attackers to execute arbitrary commands via an improperly terminated comment or phrase in the address list.", + "affected_packages": [ + + ], + "references": [ + { + "reference_id": "", + "reference_type" : "", + "url": "http://online.securityfocus.com/advisories/3778", + "severities": [ + + ] + }, + { + "reference_id": "", + "reference_type" : "", + "url": "ftp://ftp.freebsd.org/pub/FreeBSD/CERT/advisories/FreeBSD-SA-02:04.mutt.asc", + "severities": [ + + ] + }, + { + "reference_id": "", + "reference_type" : "", + "url": "http://www.debian.org/security/2002/dsa-096", + "severities": [ + + ] + }, + { + "reference_id": "", + "reference_type" : "", + "url": "http://www.mutt.org/announce/mutt-1.2.5.1-1.3.25.html", + "severities": [ + + ] + }, + { + "reference_id": "", + "reference_type" : "", + "url": "http://distro.conectiva.com.br/atualizacoes/?id=a&anuncio=000449", + "severities": [ + + ] + }, + { + "reference_id": "", + "reference_type" : "", + "url": "http://www.iss.net/security_center/static/7759.php", + "severities": [ + + ] + }, + { + "reference_id": "", + "reference_type" : "", + "url": "http://www.securityfocus.com/bid/3774", + "severities": [ + + ] + }, + { + "reference_id": "", + "reference_type" : "", + "url": "ftp://ftp.caldera.com/pub/security/OpenLinux/CSSA-2002-002.0.txt", + "severities": [ + + ] + }, + { + "reference_id": "", + "reference_type" : "", + "url": "http://www.novell.com/linux/security/advisories/2002_001_mutt_txt.html", + "severities": [ + + ] + }, + { + "reference_id": "", + "reference_type" : "", + "url": "http://marc.info/?l=bugtraq&m=100994648918287&w=2", + "severities": [ + + ] + }, + { + "reference_id": "", + "reference_type" : "", + "url": "http://www.redhat.com/support/errata/RHSA-2002-003.html", + "severities": [ + + ] + } + ], + "date_published": "2002-02-27T05:00:00+00:00", + "weaknesses": [ + + ], + "url": "" +} \ No newline at end of file diff --git a/vulnerabilities/tests/test_data/gsd/GSD-2002-0001.json b/vulnerabilities/tests/test_data/gsd/GSD-2002-0001.json new file mode 100644 index 000000000..15fd3c33f --- /dev/null +++ b/vulnerabilities/tests/test_data/gsd/GSD-2002-0001.json @@ -0,0 +1,277 @@ +{ + "GSD": { + "alias": "CVE-2002-0001", + "description": "Vulnerability in RFC822 address parser in mutt before 1.2.5.1 and mutt 1.3.x before 1.3.25 allows remote attackers to execute arbitrary commands via an improperly terminated comment or phrase in the address list.", + "id": "GSD-2002-0001", + "references": [ + "https://www.debian.org/security/2002/dsa-096", + "https://access.redhat.com/errata/RHSA-2002:003" + ] + }, + "namespaces": { + "cve.org": { + "CVE_data_meta": { + "ASSIGNER": "cve@mitre.org", + "ID": "CVE-2002-0001", + "STATE": "PUBLIC" + }, + "affects": { + "vendor": { + "vendor_data": [ + { + "product": { + "product_data": [ + { + "product_name": "n/a", + "version": { + "version_data": [ + { + "version_value": "n/a" + } + ] + } + } + ] + }, + "vendor_name": "n/a" + } + ] + } + }, + "data_format": "MITRE", + "data_type": "CVE", + "data_version": "4.0", + "description": { + "description_data": [ + { + "lang": "eng", + "value": "Vulnerability in RFC822 address parser in mutt before 1.2.5.1 and mutt 1.3.x before 1.3.25 allows remote attackers to execute arbitrary commands via an improperly terminated comment or phrase in the address list." + } + ] + }, + "problemtype": { + "problemtype_data": [ + { + "description": [ + { + "lang": "eng", + "value": "n/a" + } + ] + } + ] + }, + "references": { + "reference_data": [ + { + "name": "HPSBTL0201-011", + "refsource": "HP", + "url": "http://online.securityfocus.com/advisories/3778" + }, + { + "name": "FreeBSD-SA-02:04", + "refsource": "FREEBSD", + "url": "ftp://ftp.freebsd.org/pub/FreeBSD/CERT/advisories/FreeBSD-SA-02:04.mutt.asc" + }, + { + "name": "DSA-096", + "refsource": "DEBIAN", + "url": "http://www.debian.org/security/2002/dsa-096" + }, + { + "name": "http://www.mutt.org/announce/mutt-1.2.5.1-1.3.25.html", + "refsource": "CONFIRM", + "url": "http://www.mutt.org/announce/mutt-1.2.5.1-1.3.25.html" + }, + { + "name": "CLA-2002:449", + "refsource": "CONECTIVA", + "url": "http://distro.conectiva.com.br/atualizacoes/?id=a&anuncio=000449" + }, + { + "name": "mutt-address-handling-bo(7759)", + "refsource": "XF", + "url": "http://www.iss.net/security_center/static/7759.php" + }, + { + "name": "3774", + "refsource": "BID", + "url": "http://www.securityfocus.com/bid/3774" + }, + { + "name": "CSSA-2002-002.0", + "refsource": "CALDERA", + "url": "ftp://ftp.caldera.com/pub/security/OpenLinux/CSSA-2002-002.0.txt" + }, + { + "name": "SuSE-SA:2002:001", + "refsource": "SUSE", + "url": "http://www.novell.com/linux/security/advisories/2002_001_mutt_txt.html" + }, + { + "name": "20020101 [Announce] SECURITY: mutt-1.2.5.1 and mutt-1.3.25 released.", + "refsource": "BUGTRAQ", + "url": "http://marc.info/?l=bugtraq&m=100994648918287&w=2" + }, + { + "name": "RHSA-2002:003", + "refsource": "REDHAT", + "url": "http://www.redhat.com/support/errata/RHSA-2002-003.html" + } + ] + } + }, + "nvd.nist.gov": { + "configurations": { + "CVE_data_version": "4.0", + "nodes": [ + { + "children": [], + "cpe_match": [ + { + "cpe23Uri": "cpe:2.3:a:mutt:mutt:*:*:*:*:*:*:*:*", + "cpe_name": [], + "versionEndIncluding": "1.2.5.1", + "vulnerable": true + }, + { + "cpe23Uri": "cpe:2.3:a:mutt:mutt:*:*:*:*:*:*:*:*", + "cpe_name": [], + "versionEndIncluding": "1.3.25", + "vulnerable": true + } + ], + "operator": "OR" + } + ] + }, + "cve": { + "CVE_data_meta": { + "ASSIGNER": "cve@mitre.org", + "ID": "CVE-2002-0001" + }, + "data_format": "MITRE", + "data_type": "CVE", + "data_version": "4.0", + "description": { + "description_data": [ + { + "lang": "en", + "value": "Vulnerability in RFC822 address parser in mutt before 1.2.5.1 and mutt 1.3.x before 1.3.25 allows remote attackers to execute arbitrary commands via an improperly terminated comment or phrase in the address list." + } + ] + }, + "problemtype": { + "problemtype_data": [ + { + "description": [ + { + "lang": "en", + "value": "NVD-CWE-Other" + } + ] + } + ] + }, + "references": { + "reference_data": [ + { + "name": "DSA-096", + "refsource": "DEBIAN", + "tags": [ + "Patch" + ], + "url": "http://www.debian.org/security/2002/dsa-096" + }, + { + "name": "RHSA-2002:003", + "refsource": "REDHAT", + "tags": [ + "Patch" + ], + "url": "http://www.redhat.com/support/errata/RHSA-2002-003.html" + }, + { + "name": "http://www.mutt.org/announce/mutt-1.2.5.1-1.3.25.html", + "refsource": "CONFIRM", + "tags": [], + "url": "http://www.mutt.org/announce/mutt-1.2.5.1-1.3.25.html" + }, + { + "name": "SuSE-SA:2002:001", + "refsource": "SUSE", + "tags": [], + "url": "http://www.novell.com/linux/security/advisories/2002_001_mutt_txt.html" + }, + { + "name": "FreeBSD-SA-02:04", + "refsource": "FREEBSD", + "tags": [], + "url": "ftp://ftp.freebsd.org/pub/FreeBSD/CERT/advisories/FreeBSD-SA-02:04.mutt.asc" + }, + { + "name": "HPSBTL0201-011", + "refsource": "HP", + "tags": [], + "url": "http://online.securityfocus.com/advisories/3778" + }, + { + "name": "CSSA-2002-002.0", + "refsource": "CALDERA", + "tags": [], + "url": "ftp://ftp.caldera.com/pub/security/OpenLinux/CSSA-2002-002.0.txt" + }, + { + "name": "3774", + "refsource": "BID", + "tags": [], + "url": "http://www.securityfocus.com/bid/3774" + }, + { + "name": "mutt-address-handling-bo(7759)", + "refsource": "XF", + "tags": [], + "url": "http://www.iss.net/security_center/static/7759.php" + }, + { + "name": "CLA-2002:449", + "refsource": "CONECTIVA", + "tags": [], + "url": "http://distro.conectiva.com.br/atualizacoes/?id=a&anuncio=000449" + }, + { + "name": "20020101 [Announce] SECURITY: mutt-1.2.5.1 and mutt-1.3.25 released.", + "refsource": "BUGTRAQ", + "tags": [], + "url": "http://marc.info/?l=bugtraq&m=100994648918287&w=2" + } + ] + } + }, + "impact": { + "baseMetricV2": { + "cvssV2": { + "accessComplexity": "LOW", + "accessVector": "NETWORK", + "authentication": "NONE", + "availabilityImpact": "PARTIAL", + "baseScore": 7.5, + "confidentialityImpact": "PARTIAL", + "integrityImpact": "PARTIAL", + "vectorString": "AV:N/AC:L/Au:N/C:P/I:P/A:P", + "version": "2.0" + }, + "exploitabilityScore": 10.0, + "impactScore": 6.4, + "obtainAllPrivilege": false, + "obtainOtherPrivilege": false, + "obtainUserPrivilege": false, + "severity": "HIGH", + "userInteractionRequired": false + } + }, + "lastModifiedDate": "2016-10-18T02:15Z", + "publishedDate": "2002-02-27T05:00Z" + } + } +} \ No newline at end of file diff --git a/vulnerabilities/tests/test_data/gsd/GSD-2006-0326-expected.json b/vulnerabilities/tests/test_data/gsd/GSD-2006-0326-expected.json new file mode 100644 index 000000000..c9c1308c6 --- /dev/null +++ b/vulnerabilities/tests/test_data/gsd/GSD-2006-0326-expected.json @@ -0,0 +1,18 @@ +{ + "aliases": [ + "CVE-2006-0326", + "GSD-2006-0326" + ], + "summary": "** RESERVED ** This candidate has been reserved by an organization or individual that will use it when announcing a new security problem. When the candidate has been publicized, the details for this candidate will be provided.", + "affected_packages": [ + + ], + "references": [ + + ], + "date_published": null, + "weaknesses": [ + + ], + "url": "" +} \ No newline at end of file diff --git a/vulnerabilities/tests/test_data/gsd/GSD-2006-0326.json b/vulnerabilities/tests/test_data/gsd/GSD-2006-0326.json new file mode 100644 index 000000000..cbe477995 --- /dev/null +++ b/vulnerabilities/tests/test_data/gsd/GSD-2006-0326.json @@ -0,0 +1,26 @@ +{ + "GSD": { + "alias": "CVE-2006-0326", + "id": "GSD-2006-0326" + }, + "namespaces": { + "cve.org": { + "CVE_data_meta": { + "ASSIGNER": "cve@mitre.org", + "ID": "CVE-2006-0326", + "STATE": "RESERVED" + }, + "data_format": "MITRE", + "data_type": "CVE", + "data_version": "4.0", + "description": { + "description_data": [ + { + "lang": "eng", + "value": "** RESERVED ** This candidate has been reserved by an organization or individual that will use it when announcing a new security problem. When the candidate has been publicized, the details for this candidate will be provided." + } + ] + } + } + } +} \ No newline at end of file diff --git a/vulnerabilities/tests/test_data/gsd/GSD-2016-20005-expected.json b/vulnerabilities/tests/test_data/gsd/GSD-2016-20005-expected.json new file mode 100644 index 000000000..d7f07bcda --- /dev/null +++ b/vulnerabilities/tests/test_data/gsd/GSD-2016-20005-expected.json @@ -0,0 +1,16 @@ +{ + "aliases": ["CVE-2016-20005", "GSD-2016-20005"], + "summary": "The REST/JSON project 7.x-1.x for Drupal allows user registration bypass, aka SA-CONTRIB-2016-033. NOTE: This project is not covered by Drupal's security advisory policy.", + "affected_packages": [], + "references": [ + { + "reference_id": "", + "reference_type" : "", + "url": "https://www.drupal.org/node/2744889", + "severities": [] + } + ], + "date_published": "2021-01-01T01:15:00+00:00", + "weaknesses": [], + "url": "" +} \ No newline at end of file diff --git a/vulnerabilities/tests/test_data/gsd/GSD-2016-20005.json b/vulnerabilities/tests/test_data/gsd/GSD-2016-20005.json new file mode 100644 index 000000000..ac54ce17c --- /dev/null +++ b/vulnerabilities/tests/test_data/gsd/GSD-2016-20005.json @@ -0,0 +1,174 @@ +{ + "GSD": { + "alias": "CVE-2016-20005", + "description": "The REST/JSON project 7.x-1.x for Drupal allows user registration bypass, aka SA-CONTRIB-2016-033. NOTE: This project is not covered by Drupal's security advisory policy.", + "id": "GSD-2016-20005" + }, + "namespaces": { + "cve.org": { + "CVE_data_meta": { + "ASSIGNER": "cve@mitre.org", + "ID": "CVE-2016-20005", + "STATE": "PUBLIC" + }, + "affects": { + "vendor": { + "vendor_data": [ + { + "product": { + "product_data": [ + { + "product_name": "n/a", + "version": { + "version_data": [ + { + "version_value": "n/a" + } + ] + } + } + ] + }, + "vendor_name": "n/a" + } + ] + } + }, + "data_format": "MITRE", + "data_type": "CVE", + "data_version": "4.0", + "description": { + "description_data": [ + { + "lang": "eng", + "value": "The REST/JSON project 7.x-1.x for Drupal allows user registration bypass, aka SA-CONTRIB-2016-033. NOTE: This project is not covered by Drupal's security advisory policy." + } + ] + }, + "problemtype": { + "problemtype_data": [ + { + "description": [ + { + "lang": "eng", + "value": "n/a" + } + ] + } + ] + }, + "references": { + "reference_data": [ + { + "name": "https://www.drupal.org/node/2744889", + "refsource": "MISC", + "url": "https://www.drupal.org/node/2744889" + } + ] + } + }, + "nvd.nist.gov": { + "configurations": { + "CVE_data_version": "4.0", + "nodes": [ + { + "children": [], + "cpe_match": [ + { + "cpe23Uri": "cpe:2.3:a:rest\\/json_project:rest\\/json:*:*:*:*:*:drupal:*:*", + "cpe_name": [], + "versionEndIncluding": "7.x-1.5", + "vulnerable": true + } + ], + "operator": "OR" + } + ] + }, + "cve": { + "CVE_data_meta": { + "ASSIGNER": "cve@mitre.org", + "ID": "CVE-2016-20005" + }, + "data_format": "MITRE", + "data_type": "CVE", + "data_version": "4.0", + "description": { + "description_data": [ + { + "lang": "en", + "value": "The REST/JSON project 7.x-1.x for Drupal allows user registration bypass, aka SA-CONTRIB-2016-033. NOTE: This project is not covered by Drupal's security advisory policy." + } + ] + }, + "problemtype": { + "problemtype_data": [ + { + "description": [ + { + "lang": "en", + "value": "CWE-863" + } + ] + } + ] + }, + "references": { + "reference_data": [ + { + "name": "https://www.drupal.org/node/2744889", + "refsource": "MISC", + "tags": [ + "Third Party Advisory" + ], + "url": "https://www.drupal.org/node/2744889" + } + ] + } + }, + "impact": { + "baseMetricV2": { + "acInsufInfo": false, + "cvssV2": { + "accessComplexity": "LOW", + "accessVector": "NETWORK", + "authentication": "NONE", + "availabilityImpact": "PARTIAL", + "baseScore": 7.5, + "confidentialityImpact": "PARTIAL", + "integrityImpact": "PARTIAL", + "vectorString": "AV:N/AC:L/Au:N/C:P/I:P/A:P", + "version": "2.0" + }, + "exploitabilityScore": 10.0, + "impactScore": 6.4, + "obtainAllPrivilege": false, + "obtainOtherPrivilege": false, + "obtainUserPrivilege": false, + "severity": "HIGH", + "userInteractionRequired": false + }, + "baseMetricV3": { + "cvssV3": { + "attackComplexity": "LOW", + "attackVector": "NETWORK", + "availabilityImpact": "HIGH", + "baseScore": 9.8, + "baseSeverity": "CRITICAL", + "confidentialityImpact": "HIGH", + "integrityImpact": "HIGH", + "privilegesRequired": "NONE", + "scope": "UNCHANGED", + "userInteraction": "NONE", + "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", + "version": "3.1" + }, + "exploitabilityScore": 3.9, + "impactScore": 5.9 + } + }, + "lastModifiedDate": "2021-01-07T14:59Z", + "publishedDate": "2021-01-01T01:15Z" + } + } +} \ No newline at end of file diff --git a/vulnerabilities/tests/test_data/gsd/GSD-2022-4030-expected.json b/vulnerabilities/tests/test_data/gsd/GSD-2022-4030-expected.json new file mode 100644 index 000000000..708c84ffa --- /dev/null +++ b/vulnerabilities/tests/test_data/gsd/GSD-2022-4030-expected.json @@ -0,0 +1,33 @@ +{ + "aliases": [ + "CVE-2022-4030", + "GSD-2022-4030" + ], + "summary": "The Simple:Press plugin for WordPress is vulnerable to Path Traversal in versions up to, and including, 6.8 via the 'file' parameter which can be manipulated during user avatar deletion. This makes it possible with attackers, with minimal permissions such as a subscriber, to supply paths to arbitrary files on the server that will subsequently be deleted. This can be used to delete the wp-config.php file that can allow an attacker to configure the site and achieve remote code execution.", + "affected_packages": [ + + ], + "references": [ + { + "reference_id": "", + "reference_type" : "", + "url": "https://plugins.trac.wordpress.org/changeset?sfp_email=&sfph_mail=&reponame=&old=2804020%40simplepress&new=2804020%40simplepress&sfp_email=&sfph_mail=", + "severities": [ + + ] + }, + { + "reference_id": "", + "reference_type" : "", + "url": "https://www.wordfence.com/vulnerability-advisories-continued/#CVE-2022-4030", + "severities": [ + + ] + } + ], + "date_published": "2022-11-29T21:15:00+00:00", + "weaknesses": [ + + ], + "url": "" +} \ No newline at end of file diff --git a/vulnerabilities/tests/test_data/gsd/GSD-2022-4030.json b/vulnerabilities/tests/test_data/gsd/GSD-2022-4030.json new file mode 100644 index 000000000..a8f44c841 --- /dev/null +++ b/vulnerabilities/tests/test_data/gsd/GSD-2022-4030.json @@ -0,0 +1,188 @@ +{ + "GSD": { + "alias": "CVE-2022-4030", + "description": "The Simple:Press plugin for WordPress is vulnerable to Path Traversal in versions up to, and including, 6.8 via the 'file' parameter which can be manipulated during user avatar deletion. This makes it possible with attackers, with minimal permissions such as a subscriber, to supply paths to arbitrary files on the server that will subsequently be deleted. This can be used to delete the wp-config.php file that can allow an attacker to configure the site and achieve remote code execution.", + "id": "GSD-2022-4030" + }, + "namespaces": { + "cve.org": { + "CVE_data_meta": { + "ASSIGNER": "security@wordfence.com", + "ID": "CVE-2022-4030", + "STATE": "PUBLIC" + }, + "affects": { + "vendor": { + "vendor_data": [ + { + "product": { + "product_data": [ + { + "product_name": "Simple:Press \u2013 WordPress Forum Plugin", + "version": { + "version_data": [ + { + "version_affected": "=", + "version_value": "*" + } + ] + } + } + ] + }, + "vendor_name": "simplepress" + } + ] + } + }, + "credits": [ + { + "lang": "en", + "value": "Luca Greeb" + }, + { + "lang": "en", + "value": "Andreas Kr\u00fcger" + } + ], + "data_format": "MITRE", + "data_type": "CVE", + "data_version": "4.0", + "description": { + "description_data": [ + { + "lang": "eng", + "value": "The Simple:Press plugin for WordPress is vulnerable to Path Traversal in versions up to, and including, 6.8 via the 'file' parameter which can be manipulated during user avatar deletion. This makes it possible with attackers, with minimal permissions such as a subscriber, to supply paths to arbitrary files on the server that will subsequently be deleted. This can be used to delete the wp-config.php file that can allow an attacker to configure the site and achieve remote code execution." + } + ] + }, + "impact": { + "cvss": [ + { + "baseScore": 8.1, + "baseSeverity": "HIGH", + "vectorString": "CVSS:3.1/A:H/I:H/C:N/S:U/UI:N/PR:L/AC:L/AV:N", + "version": "3.1" + } + ] + }, + "problemtype": { + "problemtype_data": [ + { + "description": [ + { + "lang": "eng", + "value": "CWE-22 Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')" + } + ] + } + ] + }, + "references": { + "reference_data": [ + { + "name": "https://plugins.trac.wordpress.org/changeset?sfp_email=&sfph_mail=&reponame=&old=2804020%40simplepress&new=2804020%40simplepress&sfp_email=&sfph_mail=", + "refsource": "MISC", + "url": "https://plugins.trac.wordpress.org/changeset?sfp_email=&sfph_mail=&reponame=&old=2804020%40simplepress&new=2804020%40simplepress&sfp_email=&sfph_mail=" + }, + { + "name": "https://www.wordfence.com/vulnerability-advisories-continued/#CVE-2022-4030", + "refsource": "MISC", + "url": "https://www.wordfence.com/vulnerability-advisories-continued/#CVE-2022-4030" + } + ] + } + }, + "nvd.nist.gov": { + "configurations": { + "CVE_data_version": "4.0", + "nodes": [ + { + "children": [], + "cpe_match": [ + { + "cpe23Uri": "cpe:2.3:a:simple-press:simple\\:press:*:*:*:*:*:wordpress:*:*", + "cpe_name": [], + "versionEndIncluding": "6.8.0", + "vulnerable": true + } + ], + "operator": "OR" + } + ] + }, + "cve": { + "CVE_data_meta": { + "ASSIGNER": "security@wordfence.com", + "ID": "CVE-2022-4030" + }, + "data_format": "MITRE", + "data_type": "CVE", + "data_version": "4.0", + "description": { + "description_data": [ + { + "lang": "en", + "value": "The Simple:Press plugin for WordPress is vulnerable to Path Traversal in versions up to, and including, 6.8 via the 'file' parameter which can be manipulated during user avatar deletion. This makes it possible with attackers, with minimal permissions such as a subscriber, to supply paths to arbitrary files on the server that will subsequently be deleted. This can be used to delete the wp-config.php file that can allow an attacker to configure the site and achieve remote code execution." + } + ] + }, + "problemtype": { + "problemtype_data": [ + { + "description": [ + { + "lang": "en", + "value": "CWE-22" + } + ] + } + ] + }, + "references": { + "reference_data": [ + { + "name": "https://plugins.trac.wordpress.org/changeset?sfp_email=&sfph_mail=&reponame=&old=2804020%40simplepress&new=2804020%40simplepress&sfp_email=&sfph_mail=", + "refsource": "MISC", + "tags": [ + "Patch", + "Third Party Advisory" + ], + "url": "https://plugins.trac.wordpress.org/changeset?sfp_email=&sfph_mail=&reponame=&old=2804020%40simplepress&new=2804020%40simplepress&sfp_email=&sfph_mail=" + }, + { + "name": "https://www.wordfence.com/vulnerability-advisories-continued/#CVE-2022-4030", + "refsource": "MISC", + "tags": [ + "Third Party Advisory" + ], + "url": "https://www.wordfence.com/vulnerability-advisories-continued/#CVE-2022-4030" + } + ] + } + }, + "impact": { + "baseMetricV3": { + "cvssV3": { + "attackComplexity": "LOW", + "attackVector": "NETWORK", + "availabilityImpact": "HIGH", + "baseScore": 8.1, + "baseSeverity": "HIGH", + "confidentialityImpact": "NONE", + "integrityImpact": "HIGH", + "privilegesRequired": "LOW", + "scope": "UNCHANGED", + "userInteraction": "NONE", + "vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H", + "version": "3.1" + }, + "exploitabilityScore": 2.8, + "impactScore": 5.2 + } + }, + "lastModifiedDate": "2022-12-01T18:41Z", + "publishedDate": "2022-11-29T21:15Z" + } + } +} \ No newline at end of file diff --git a/vulnerabilities/tests/test_data/gsd/GSD-2023-1000387.json b/vulnerabilities/tests/test_data/gsd/GSD-2023-1000387.json new file mode 100644 index 000000000..44b7ec42a --- /dev/null +++ b/vulnerabilities/tests/test_data/gsd/GSD-2023-1000387.json @@ -0,0 +1,61 @@ +{ + "GSD": { + "vendor_name": "Linux", + "product_name": "Kernel", + "product_version": "versions from v6.0 to before v6.0.19", + "vulnerability_type": "unspecified", + "affected_component": "unspecified", + "attack_vector": "unspecified", + "impact": "unspecified", + "credit": "", + "references": [ + "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=0f28cca87e9afc22280c44d378d2a6e249933977", + "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=2d5a6742a242091292cc0a2b607be701a45d0c4e" + ], + "extended_references": [ + { + "type": "commit", + "value": "0f28cca87e9afc22280c44d378d2a6e249933977", + "note": "introduced" + }, + { + "type": "commit", + "value": "2d5a6742a242091292cc0a2b607be701a45d0c4e", + "note": "fixed" + } + ], + "reporter": "joshbressers", + "reporter_id": 1692786, + "notes": "", + "description": "drm/amdkfd: Fix kernel warning during topology setup\n\nThis is an automated ID intended to aid in discovery of potential security vulnerabilities. The actual impact and attack plausibility have not yet been proven.\nThis ID is fixed in Linux Kernel version v6.0.19 by commit 2d5a6742a242091292cc0a2b607be701a45d0c4e, it was introduced in version v6.0 by commit 0f28cca87e9afc22280c44d378d2a6e249933977. For more details please see the references link." + }, + "OSV": { + "id": "GSD-2023-1000387", + "modified": "2023-01-17T17:35:43.401817Z", + "published": "2023-01-17T17:35:43.401817Z", + "summary": "drm/amdkfd: Fix kernel warning during topology setup", + "details": "drm/amdkfd: Fix kernel warning during topology setup\n\nThis is an automated ID intended to aid in discovery of potential security vulnerabilities. The actual impact and attack plausibility have not yet been proven.\nThis ID is fixed in Linux Kernel version v6.0.19 by commit 2d5a6742a242091292cc0a2b607be701a45d0c4e, it was introduced in version v6.0 by commit 0f28cca87e9afc22280c44d378d2a6e249933977. For more details please see the references link.", + "affected": [ + { + "package": { + "name": "Kernel", + "ecosystem": "Linux" + }, + "ranges": [ + { + "type": "GIT", + "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/", + "events": [ + { + "introduced": "0f28cca87e9afc22280c44d378d2a6e249933977" + }, + { + "limit": "2d5a6742a242091292cc0a2b607be701a45d0c4e" + } + ] + } + ] + } + ] + } +} \ No newline at end of file diff --git a/vulnerabilities/tests/test_gsd.py b/vulnerabilities/tests/test_gsd.py new file mode 100644 index 000000000..34099f947 --- /dev/null +++ b/vulnerabilities/tests/test_gsd.py @@ -0,0 +1,240 @@ +# +# 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/nexB/vulnerablecode for support or download. +# See https://aboutcode.org for more information about nexB OSS projects. +# +import datetime +import json +import os +from unittest import TestCase + +from vulnerabilities.importer import Reference +from vulnerabilities.importers.gsd import get_aliases +from vulnerabilities.importers.gsd import get_description +from vulnerabilities.importers.gsd import get_published_date_nvd_nist_gov +from vulnerabilities.importers.gsd import get_references +from vulnerabilities.importers.gsd import get_severities +from vulnerabilities.importers.gsd import get_summary +from vulnerabilities.importers.gsd import parse_advisory_data +from vulnerabilities.tests import util_tests + +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) +TEST_DATA = os.path.join(BASE_DIR, "test_data/gsd") + + +class TestGSDImporter(TestCase): + def test_to_advisories1(self): + with open(os.path.join(TEST_DATA, "GSD-2016-20005.json")) as f: + raw_data = json.load(f) + imported_data = parse_advisory_data(raw_data, "GSD-2016-20005.json") + expected_file = os.path.join(TEST_DATA, "GSD-2016-20005-expected.json") + result = imported_data.to_dict() + util_tests.check_results_against_json(result, expected_file) + + def test_to_advisories2(self): + with open(os.path.join(TEST_DATA, "GSD-2022-4030.json")) as f: + raw_data = json.load(f) + imported_data = parse_advisory_data(raw_data, "GSD-2022-4030.json") + expected_file = os.path.join(TEST_DATA, "GSD-2022-4030-expected.json") + result = imported_data.to_dict() + util_tests.check_results_against_json(result, expected_file) + + def test_to_advisories3(self): + with open(os.path.join(TEST_DATA, "GSD-2002-0001.json")) as f: + raw_data = json.load(f) + imported_data = parse_advisory_data(raw_data, "GSD-2022-4030.json") + expected_file = os.path.join(TEST_DATA, "GSD-2002-0001-expected.json") + result = imported_data.to_dict() + util_tests.check_results_against_json(result, expected_file) + + def test_to_advisories4(self): + with open(os.path.join(TEST_DATA, "GSD-2006-0326.json")) as f: + raw_data = json.load(f) + imported_data = parse_advisory_data(raw_data, "GSD-2022-4030.json") + expected_file = os.path.join(TEST_DATA, "GSD-2006-0326-expected.json") + result = imported_data.to_dict() + util_tests.check_results_against_json(result, expected_file) + + def test_get_references(self): + assert get_references( + { + "references": { + "reference_data": [ + { + "name": "https://kc.mcafee.com/corporate/index?page=content&id=SB10198", + "refsource": "CONFIRM", + "tags": ["Vendor Advisory"], + "url": "https://kc.mcafee.com/corporate/index?page=content&id=SB10198", + } + ] + } + } + ) == [ + Reference( + reference_id="", + url="https://kc.mcafee.com/corporate/index?page=content&id=SB10198", + severities=[], + ) + ] + + def test_get_description(self): + assert get_description( + { + "description": { + "description_data": [ + { + "lang": "eng", + "value": "User Name Disclosure in the server in McAfee Network Data Loss Prevention (NDLP) 9.3.x allows remote attackers to view user information via the appliance web interface.", + } + ] + } + } + ) == [ + "User Name Disclosure in the server in McAfee Network Data Loss Prevention (NDLP) 9.3.x allows remote attackers to view user information via the appliance web interface." + ] + + def test_get_aliases_cve_org(self): + assert get_aliases( + { + "CVE_data_meta": { + "ASSIGNER": "secure@intel.com", + "ID": "CVE-2017-4017", + "STATE": "PUBLIC", + } + } + ) == ["CVE-2017-4017"] + assert get_aliases( + { + "CVE_data_meta": { + "ASSIGNER": "secure@intel.com", + "ID": "CVE-2017-4017", + "STATE": "PUBLIC", + }, + "source": {"advisory": "GHSA-v8x6-59g4-5g3w", "discovery": "UNKNOWN"}, + } + ) == ["CVE-2017-4017", "GHSA-v8x6-59g4-5g3w"] + assert get_aliases( + {"source": {"advisory": "GHSA-v8x6-59g4-5g3w", "discovery": "UNKNOWN"}} + ) == ["GHSA-v8x6-59g4-5g3w"] + + def test_get_summary(self): + assert ( + get_summary({"CVE_data_meta": {"TITLE": "DoS vulnerability: Invalid Accent Colors"}}) + == "DoS vulnerability: Invalid Accent Colors" + ) + + def test_get_severities(self): + assert get_severities( + { + "impact": { + "cvss": { + "attackComplexity": "LOW", + "attackVector": "NETWORK", + "availabilityImpact": "HIGH", + "baseScore": 5.7, + "baseSeverity": "MEDIUM", + "confidentialityImpact": "NONE", + "integrityImpact": "NONE", + "privilegesRequired": "LOW", + "scope": "UNCHANGED", + "userInteraction": "REQUIRED", + "vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:N/A:H", + "version": "3.1", + } + } + } + ) == ["CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:N/A:H"] + assert get_severities( + { + "impact": { + "baseMetricV2": { + "acInsufInfo": False, + "cvssV2": { + "accessComplexity": "LOW", + "accessVector": "NETWORK", + "authentication": "NONE", + "availabilityImpact": "PARTIAL", + "baseScore": 7.5, + "confidentialityImpact": "PARTIAL", + "integrityImpact": "PARTIAL", + "vectorString": "AV:N/AC:L/Au:N/C:P/I:P/A:P", + "version": "2.0", + }, + "exploitabilityScore": 10.0, + "impactScore": 6.4, + "obtainAllPrivilege": False, + "obtainOtherPrivilege": False, + "obtainUserPrivilege": False, + "severity": "HIGH", + "userInteractionRequired": False, + }, + "baseMetricV3": { + "cvssV3": { + "attackComplexity": "LOW", + "attackVector": "NETWORK", + "availabilityImpact": "HIGH", + "baseScore": 9.8, + "baseSeverity": "CRITICAL", + "confidentialityImpact": "HIGH", + "integrityImpact": "HIGH", + "privilegesRequired": "NONE", + "scope": "UNCHANGED", + "userInteraction": "NONE", + "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", + "version": "3.1", + }, + "exploitabilityScore": 3.9, + "impactScore": 5.9, + }, + } + } + ) == ["AV:N/AC:L/Au:N/C:P/I:P/A:P", "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"] + + assert get_severities( + { + "impact": { + "cvss": [ + { + "baseScore": 8.1, + "baseSeverity": "HIGH", + "vectorString": "CVSS:3.1/A:H/I:H/C:N/S:U/UI:N/PR:L/AC:L/AV:N", + "version": "3.1", + } + ] + } + } + ) == ["CVSS:3.1/A:H/I:H/C:N/S:U/UI:N/PR:L/AC:L/AV:N"] + + assert get_severities( + { + "impact": { + "baseMetricV3": { + "cvssV3": { + "attackComplexity": "LOW", + "attackVector": "NETWORK", + "availabilityImpact": "HIGH", + "baseScore": 8.1, + "baseSeverity": "HIGH", + "confidentialityImpact": "NONE", + "integrityImpact": "HIGH", + "privilegesRequired": "LOW", + "scope": "UNCHANGED", + "userInteraction": "NONE", + "vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H", + "version": "3.1", + }, + "exploitabilityScore": 2.8, + "impactScore": 5.2, + } + } + } + ) == ["CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H"] + + def test_get_published_date_nvd_nist_gov(self): + assert get_published_date_nvd_nist_gov( + {"publishedDate": "2022-06-23T07:15Z"} + ) == datetime.datetime(2022, 6, 23, 7, 15, 0, 0).replace(tzinfo=datetime.timezone.utc) + assert get_published_date_nvd_nist_gov({}) is None