def test_npm_geddy(self): args = {'ecosystem': 'npm', 'name': 'geddy', 'version': '13.0.7'} task = CVEcheckerTask.create_test_instance(task_name='security_issues') results = task.execute(args) assert isinstance(results, dict) assert set(results.keys()) == {'details', 'status', 'summary'} assert results['status'] == 'success' assert results['summary'] == ['CVE-2015-5688'] # http://www.cvedetails.com/version/186008/Geddyjs-Geddy-13.0.7.html expected_details = [{ "cvss": { "score": 5.0, "vector": "AV:N/AC:L/Au:N/C:P/I:N/A:N" }, "description": "Directory traversal vulnerability in lib/app/index.js in Geddy " "before 13.0.8 for Node.js allows remote attackers " "to read arbitrary files via a ..%2f (dot dot encoded slash) " "in the PATH_INFO to the default URI.", "id": "CVE-2015-5688", "references": [ "http://cve.mitre.org/cgi-bin/cvename.cgi?name=2015-5688", "http://www.cvedetails.com/cve-details.php?t=1&cve_id=CVE-2015-5688", "https://github.com/geddy/geddy/commit/2de63b68b3aa6c08848f261ace550a37959ef231", "https://github.com/geddy/geddy/issues/697", "https://github.com/geddy/geddy/pull/699", "https://github.com/geddy/geddy/releases/tag/v13.0.8", "https://nodesecurity.io/advisories/geddy-directory-traversal", "https://web.nvd.nist.gov/view/vuln/detail?vulnId=2015-5688" ], "severity": "medium"}] assert_equal(results.get('details'), expected_details)
def test_maven_commons_compress(self): """Tests CVE reports for selected packages from Maven ecosystem.""" args = { 'ecosystem': 'maven', 'name': 'org.apache.commons:commons-compress', 'version': '1.4' } task = CVEcheckerTask.create_test_instance(task_name='security_issues') results = task.execute(arguments=args) assert isinstance(results, dict) assert set(results.keys()) == {'details', 'status', 'summary'} expected_details = [{ "attribution": "https://github.com/victims/victims-cve-db, CC BY-SA 4.0, modified", "cvss": { "score": 5.0, "vector": "AV:N/AC:L/Au:N/C:N/I:N/A:P" }, "description": "Algorithmic complexity vulnerability in the sorting algorithms " "in bzip2 compressing stream (BZip2CompressorOutputStream) " "in Apache Commons Compress before 1.4.1 allows remote attackers " "to cause a denial of service (CPU consumption) via a file " "with many repeating inputs.\n", "id": "CVE-2012-2098", "references": ["https://nvd.nist.gov/vuln/detail/CVE-2012-2098"], "severity": "medium" }] assert_equal(results.get('details'), expected_details, results.get('details'))
def test_nuget_system_net_http(self): """Tests CVE reports for selected package from Nuget ecosystem.""" args = { 'ecosystem': 'nuget', 'name': 'System.Net.Http', 'version': '4.1.1' } task = CVEcheckerTask.create_test_instance(task_name='security_issues') results = task.execute(arguments=args) assert isinstance(results, dict) assert set(results.keys()) == {'details', 'status', 'summary'} # https://github.com/dotnet/announcements/issues/12 # http://www.cvedetails.com/version/220163/Microsoft-System.net.http-4.1.1.html assert set(results.get('summary')) >= { 'CVE-2017-0247', 'CVE-2017-0248', 'CVE-2017-0249', 'CVE-2017-0256' } details = results.get('details') assert isinstance(details, list) and len(details) >= 4 for detail in details: assert set(detail.keys()) == { 'cvss', 'description', 'id', 'references', 'severity' } assert detail['description'] assert detail['references'] assert set(detail['cvss'].keys()) == {'score', 'vector'}
def test_python_requests(self): """To make sure that python CPE suppression works (issue#131).""" extracted = os.path.join( os.path.dirname( os.path.abspath(__file__)), '..', 'data', 'pypi', 'requests-2.5.3') args = {'ecosystem': 'pypi', 'name': 'requests', 'version': '2.5.3'} flexmock(EPVCache).should_receive('get_extracted_source_tarball').and_return(extracted) task = CVEcheckerTask.create_test_instance(task_name='security_issues') results = task.execute(arguments=args) assert isinstance(results, dict) assert set(results.keys()) == {'details', 'status', 'summary'} assert results['status'] == 'success' assert results['summary'] == ['CVE-2015-2296'] # http://www.cvedetails.com/version/180634/Python-requests-Requests-2.5.3.html expected_details = [{ "cvss": { "score": 6.8, "vector": "AV:N/AC:M/Au:?/C:P/I:P/A:P" }, "description": "The resolve_redirects function in sessions.py in requests 2.1.0 " "through 2.5.3 allows remote attackers to conduct session fixation " "attacks via a cookie without a host value in a redirect.", "id": "CVE-2015-2296", "references": [ "https://warehouse.python.org/project/requests/2.6.0/", "https://github.com/kennethreitz/requests/commit/" "3bd8afbff29e50b38f889b2f688785a669b9aafc", "http://www.openwall.com/lists/oss-security/2015/03/14/4", "http://www.openwall.com/lists/oss-security/2015/03/15/1", "http://www.ubuntu.com/usn/USN-2531-1", "http://advisories.mageia.org/MGASA-2015-0120.html" ], "severity": "Medium"}] assert_equal(results.get('details'), expected_details)
def test_python_mako(self): extracted = os.path.join( os.path.dirname( os.path.abspath(__file__)), '..', 'data', 'pypi', 'Mako-0.3.3') args = {'ecosystem': 'pypi', 'name': 'mako', 'version': '0.3.3'} flexmock(EPVCache).should_receive('get_extracted_source_tarball').and_return(extracted) task = CVEcheckerTask.create_test_instance(task_name='security_issues') results = task.execute(arguments=args) assert isinstance(results, dict) assert set(results.keys()) == {'details', 'status', 'summary'} assert results['status'] == 'success' assert results['summary'] == ['CVE-2010-2480'] # http://www.cvedetails.com/version/94328/Makotemplates-Mako-0.3.3.html expected_details = [{ "cvss": { "score": 4.3, "vector": "AV:N/AC:M/Au:?/C:?/I:P/A:?" }, "description": "Mako before 0.3.4 relies on the cgi.escape function in the Python " "standard library for cross-site scripting (XSS) protection, " "which makes it easier for remote attackers to conduct XSS attacks via " "vectors involving single-quote characters and a JavaScript onLoad " "event handler for a BODY element.", "id": "CVE-2010-2480", "references": [ "http://www.makotemplates.org/CHANGES", "http://bugs.python.org/issue9061", "http://lists.opensuse.org/opensuse-security-announce/2010-08/msg00001.html" ], "severity": "Medium"}] assert_equal(results.get('details'), expected_details)
def test_maven_commons_collections(self): jar_path = os.path.join( os.path.dirname( os.path.abspath(__file__)), '..', 'data', 'maven', 'commons-collections-3.2.1.jar') args = {'ecosystem': 'maven', 'name': 'commons-collections:commons-collections', 'version': '3.2.1'} flexmock(EPVCache).should_receive('get_source_tarball').and_return(jar_path) task = CVEcheckerTask.create_test_instance(task_name='source_licenses') results = task.execute(arguments=args) assert isinstance(results, dict) assert set(results.keys()) == {'details', 'status', 'summary'} expected_details = [{ "cvss": { "score": 7.5, "vector": "AV:N/AC:L/Au:?/C:P/I:P/A:P" }, "description": "Serialized-object interfaces in certain Cisco Collaboration and " "Social Media; Endpoint Clients and Client Software; Network " "Application, Service, and Acceleration; Network and Content Security " "Devices; Network Management and Provisioning; Routing and Switching - " "Enterprise and Service Provider; Unified Computing; Voice and Unified " "Communications Devices; Video, Streaming, TelePresence, and " "Transcoding Devices; Wireless; and Cisco Hosted Services products " "allow remote attackers to execute arbitrary commands via a crafted " "serialized Java object, related to the " "Apache Commons Collections (ACC) library.", "id": "CVE-2015-6420", "references": [ "http://www.securityfocus.com/bid/78872", "https://www.tenable.com/security/research/tra-2017-23", "https://www.tenable.com/security/research/tra-2017-14", "https://h20566.www2.hpe.com/portal/site/hpsc/public/kb/" "docDisplay?docId=emr_na-c05376917", "https://h20566.www2.hpe.com/portal/site/hpsc/public/kb/" "docDisplay?docId=emr_na-c05390722", "http://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/" "cisco-sa-20151209-java-deserialization" ], "severity": "High"}, { "cvss": { "score": 7.5, "vector": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H" }, "description": "It was found that the Apache commons-collections library permitted " "code execution when deserializing objects involving a specially " "constructed chain of classes. A remote attacker could use this flaw to " "execute arbitrary code with the permissions of the application using " "the commons-collections library.\n", "id": "CVE-2015-7501", "references": [ "http://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-" "opennms-and-your-application-have-in-common-this-vulnerability/"], "severity": "critical", 'attribution': 'https://github.com/victims/victims-cve-db, CC BY-SA 4.0, modified' } ] assert_equal(results.get('details'), expected_details)
def test_npm_servestatic_not_affected(self): """Tests CVE reports for selected package from NPM ecosystem.""" args = {'ecosystem': 'npm', 'name': 'serve-static', 'version': '1.7.5'} task = CVEcheckerTask.create_test_instance(task_name='security_issues') results = task.execute(args) assert isinstance(results, dict) assert set(results.keys()) == {'details', 'status', 'summary'} assert results['status'] == 'success' assert results['summary'] == [] assert_equal(results.get('details'), [])
def test_python_salt(self): """ To make sure we can scan source with standalone PKG-INFO https://github.com/jeremylong/DependencyCheck/issues/896 """ pkg_info = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'data', 'pypi', 'salt-2016.11.6', 'PKG-INFO') args = {'ecosystem': 'pypi', 'name': 'salt', 'version': '2016.11.6'} with tempdir() as extracted: # We need a write-access into extracted/ copy(pkg_info, extracted) flexmock(EPVCache).should_receive( 'get_extracted_source_tarball').and_return(extracted) task = CVEcheckerTask.create_test_instance( task_name='source_licenses') results = task.execute(arguments=args) assert isinstance(results, dict) assert set(results.keys()) == {'details', 'status', 'summary'} assert results['status'] == 'success' assert results['summary'] == ['CVE-2017-12791'] # http://www.cvedetails.com/version/222059/Saltstack-Salt-2016.11.6.html expected_details = [{ "cvss": { "score": 7.5, "vector": "AV:N/AC:L/Au:?/C:P/I:P/A:P" }, "description": "Directory traversal vulnerability in minion id validation in " "SaltStack Salt before 2016.11.7 and 2017.7.x before 2017.7.1 " "allows remote minions with incorrect credentials to authenticate " "to a master via a crafted minion ID.", "id": "CVE-2017-12791", "references": [ "http://www.securityfocus.com/bid/100384", "https://bugzilla.redhat.com/show_bug.cgi?id=1482006", "https://github.com/saltstack/salt/pull/42944", "https://docs.saltstack.com/en/2016.11/topics/releases/2016.11.7.html", "https://docs.saltstack.com/en/latest/topics/releases/2017.7.1.html", "https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=872399" ], "severity": "High" }] assert_equal(results.get('details'), expected_details)
def test_maven_commons_collections(self): """Tests CVE reports for selected packages from Maven ecosystem.""" jar_path = str( Path(__file__).parent.parent / 'data/maven/commons-collections-3.2.1.jar') args = { 'ecosystem': 'maven', 'name': 'commons-collections:commons-collections', 'version': '3.2.1' } flexmock(EPVCache).should_receive('get_source_tarball').and_return( jar_path) task = CVEcheckerTask.create_test_instance(task_name='security_issues') results = task.execute(arguments=args) assert isinstance(results, dict) assert set(results.keys()) == {'details', 'status', 'summary'} expected_details = [{ 'severity': 'critical', 'description': 'It was found that the Apache commons-collections library ' 'permitted code execution when deserializing objects involving ' 'a specially constructed chain of classes. A remote attacker ' 'could use this flaw to execute arbitrary code with the permissions ' 'of the application using the commons-collections library.\n', 'references': [ 'http://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere' '-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/' ], 'attribution': 'https://github.com/victims/victims-cve-db, CC BY-SA 4.0, modified', 'cvss': { 'vector': 'CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H', 'score': 7.5 }, 'id': 'CVE-2015-7501' }] assert_equal(results.get('details'), expected_details, results.get('details'))
def test_python_pyjwt(self): """Tests CVE reports for selected package from PyPi ecosystem.""" args = {'ecosystem': 'pypi', 'name': 'pyjwt', 'version': '1.5.0'} task = CVEcheckerTask.create_test_instance(task_name='security_issues') results = task.execute(arguments=args) assert isinstance(results, dict) assert set(results.keys()) == {'details', 'status', 'summary'} assert results['status'] == 'success' assert results['summary'] == ['CVE-2017-11424'] # http://www.cvedetails.com/version/94328/Makotemplates-Mako-0.3.3.html expected_details = [{ "attribution": "https://github.com/victims/victims-cve-db, CC BY-SA 4.0, modified", "cvss": { "score": 5.0, "vector": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N" }, "description": "In PyJWT 1.5.0 and below the `invalid_strings` check in " "`HMACAlgorithm.prepare_key` does not account for all PEM " "encoded public keys. Specifically, the PKCS1 PEM encoded " "format would be allowed because it is prefaced with the string " "`-----BEGIN RSA PUBLIC KEY-----` which is not accounted for. " "This enables symmetric/asymmetric key confusion attacks against " "users using the PKCS1 PEM encoded public keys, which would allow " "an attacker to craft JWTs from scratch.\n", "id": "CVE-2017-11424", "references": [ "https://github.com/jpadilla/pyjwt/pull/277", "https://nvd.nist.gov/vuln/detail/CVE-2017-11424" ], "severity": "high" }] assert_equal(results.get('details'), expected_details)
def test_npm_servestatic(self): """Tests CVE reports for selected package from NPM ecosystem.""" args = {'ecosystem': 'npm', 'name': 'serve-static', 'version': '1.6.4'} task = CVEcheckerTask.create_test_instance(task_name='security_issues') results = task.execute(args) assert isinstance(results, dict) assert set(results.keys()) == {'details', 'status', 'summary'} assert results['status'] == 'success' assert results['summary'] == ['CVE-2015-1164'] # http://www.cvedetails.com/version/186008/Geddyjs-Geddy-13.0.7.html expected_details = [{ "attribution": "https://github.com/victims/victims-cve-db, CC BY-SA 4.0, modified", "cvss": { "score": 4.3, "vector": "AV:N/AC:M/Au:N/C:N/I:P/A:N" }, "description": "Open redirect vulnerability in the serve-static plugin " "before 1.7.2 for Node.js, when mounted at the root, allows " "remote attackers to redirect users to arbitrary web sites " "and conduct phishing attacks via a // (slash slash) followed " "by a domain in the PATH_INFO to the default URI.\n", "id": "CVE-2015-1164", "references": [ "http://nodesecurity.io/advisories/serve-static-open-redirect", "https://bugzilla.redhat.com/show_bug.cgi?id=1181917", "https://github.com/expressjs/serve-static/issues/26", "https://nvd.nist.gov/vuln/detail/CVE-2015-1164", "https://github.com/expressjs/serve-static/blob/master/HISTORY.md#165--2015-02-04" ], "severity": "medium" }] assert_equal(results.get('details'), expected_details)
def test_maven_commons_collections(self): jar_path = os.path.join( os.path.dirname( os.path.abspath(__file__)), '..', 'data', 'maven', 'commons-collections-3.2.1.jar') args = {'ecosystem': 'maven', 'name': 'commons-collections:commons-collections', 'version': '3.2.1'} flexmock(EPVCache).should_receive('get_source_tarball').and_return(jar_path) task = CVEcheckerTask.create_test_instance(task_name='security_issues') results = task.execute(arguments=args) assert isinstance(results, dict) assert set(results.keys()) == {'details', 'status', 'summary'} expected_details = [{ "cvss": { "score": 7.5, "vector": "AV:N/AC:L/Au:?/C:P/I:P/A:P" }, "description": "Serialized-object interfaces in certain Cisco Collaboration and " "Social Media; Endpoint Clients and Client Software; Network " "Application, Service, and Acceleration; Network and Content Security " "Devices; Network Management and Provisioning; Routing and Switching - " "Enterprise and Service Provider; Unified Computing; Voice and Unified " "Communications Devices; Video, Streaming, TelePresence, and " "Transcoding Devices; Wireless; and Cisco Hosted Services products " "allow remote attackers to execute arbitrary commands via a crafted " "serialized Java object, related to the " "Apache Commons Collections (ACC) library.", "id": "CVE-2015-6420", "references": [ "http://www.securityfocus.com/bid/78872", "https://www.tenable.com/security/research/tra-2017-23", "https://www.tenable.com/security/research/tra-2017-14", "https://h20566.www2.hpe.com/portal/site/hpsc/public/kb/" "docDisplay?docId=emr_na-c05376917", "https://h20566.www2.hpe.com/portal/site/hpsc/public/kb/" "docDisplay?docId=emr_na-c05390722", "http://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/" "cisco-sa-20151209-java-deserialization", "https://www.kb.cert.org/vuls/id/576313" ], "severity": "High" }, { "cvss": { "score": 7.5, "vector": "AV:N/AC:L/Au:?/C:P/I:P/A:P" }, "description": "In Apache Synapse, by default no authentication is required for Java " "Remote Method Invocation (RMI). So Apache Synapse 3.0.1 or all " "previous releases (3.0.0, 2.1.0, 2.0.0, 1.2, 1.1.2, 1.1.1) allows " "remote code execution attacks that can be performed by injecting " "specially crafted serialized objects. And the presence of Apache " "Commons Collections 3.2.1 (commons-collections-3.2.1.jar) or previous " "versions in Synapse distribution makes this exploitable. To mitigate " "the issue, we need to limit RMI access to trusted users only. Further " "upgrading to 3.0.1 version will eliminate the risk of having said " "Commons Collection version. In Synapse 3.0.1, Commons Collection has " "been updated to 3.2.2 version.", "id": "CVE-2017-15708", "references": [ "http://www.securityfocus.com/bid/102154", "https://lists.apache.org/thread.html/" "77f2accf240d25d91b47033e2f8ebec84ffbc6e6627112b2f98b66c9@%3C" "dev.synapse.apache.org%3E" ], "severity": "High" }, { "cvss": { "score": 7.5, "vector": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H" }, "description": "It was found that the Apache commons-collections library permitted " "code execution when deserializing objects involving a specially " "constructed chain of classes. A remote attacker could use this flaw to " "execute arbitrary code with the permissions of the application using " "the commons-collections library.\n", "id": "CVE-2015-7501", "references": [ "http://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-" "opennms-and-your-application-have-in-common-this-vulnerability/"], "severity": "critical", 'attribution': 'https://github.com/victims/victims-cve-db, CC BY-SA 4.0, modified' }] assert_equal(results.get('details'), expected_details)
def test_python_salt(self): """To make sure we can scan source with standalone PKG-INFO. https://github.com/jeremylong/DependencyCheck/issues/896 """ pkg_info = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'data', 'pypi', 'salt-2016.11.6', 'PKG-INFO') args = {'ecosystem': 'pypi', 'name': 'salt', 'version': '2016.11.6'} with TemporaryDirectory() as extracted: # We need a write-access into extracted/ copy(pkg_info, extracted) flexmock(EPVCache).should_receive('get_extracted_source_tarball').and_return(extracted) task = CVEcheckerTask.create_test_instance(task_name='security_issues') results = task.execute(arguments=args) assert isinstance(results, dict) assert set(results.keys()) == {'details', 'status', 'summary'} assert results['status'] == 'success' assert results['summary'] == ['CVE-2017-12791', 'CVE-2017-14695', 'CVE-2017-14696'] # http://www.cvedetails.com/version/222059/Saltstack-Salt-2016.11.6.html expected_details = [ { "cvss": { "score": 7.5, "vector": "AV:N/AC:L/Au:?/C:P/I:P/A:P" }, "description": "Directory traversal vulnerability in minion id validation in " "SaltStack Salt before 2016.11.7 and 2017.7.x before 2017.7.1 " "allows remote minions with incorrect credentials to authenticate " "to a master via a crafted minion ID.", "id": "CVE-2017-12791", "references": [ "http://www.securityfocus.com/bid/100384", "https://bugzilla.redhat.com/show_bug.cgi?id=1482006", "https://github.com/saltstack/salt/pull/42944", "https://docs.saltstack.com/en/2016.11/topics/releases/2016.11.7.html", "https://docs.saltstack.com/en/latest/topics/releases/2017.7.1.html", "https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=872399" ], "severity": "High" }, { "cvss": { "score": 7.5, "vector": "AV:N/AC:L/Au:?/C:P/I:P/A:P" }, "description": "Directory traversal vulnerability in minion id validation " "in SaltStack Salt before 2016.3.8, 2016.11.x before 2016.11.8, " "and 2017.7.x before 2017.7.2 allows remote minions with incorrect " "credentials to authenticate to a master via a crafted minion ID. " "NOTE: this vulnerability exists because of an incomplete fix " "for CVE-2017-12791.", "id": "CVE-2017-14695", "references": [ "https://docs.saltstack.com/en/latest/topics/releases/2016.11.8.html", "https://docs.saltstack.com/en/latest/topics/releases/2016.3.8.html", "http://lists.opensuse.org/opensuse-updates/2017-10/msg00073.html", "https://bugzilla.redhat.com/show_bug.cgi?id=1500748", "https://github.com/saltstack/salt/commit/" "80d90307b07b3703428ecbb7c8bb468e28a9ae6d", "http://lists.opensuse.org/opensuse-updates/2017-10/msg00075.html", "https://docs.saltstack.com/en/latest/topics/releases/2017.7.2.html" ], "severity": "High" }, { "cvss": { "score": 5.0, "vector": "AV:N/AC:L/Au:?/C:?/I:?/A:P" }, "description": "SaltStack Salt before 2016.3.8, 2016.11.x before 2016.11.8, " "and 2017.7.x before 2017.7.2 allows remote attackers to cause " "a denial of service via a crafted authentication request.", "id": "CVE-2017-14696", "references": [ "https://github.com/saltstack/salt/commit/" "5f8b5e1a0f23fe0f2be5b3c3e04199b57a53db5b", "https://docs.saltstack.com/en/latest/topics/releases/2016.11.8.html", "https://docs.saltstack.com/en/latest/topics/releases/2016.3.8.html", "http://lists.opensuse.org/opensuse-updates/2017-10/msg00073.html", "http://lists.opensuse.org/opensuse-updates/2017-10/msg00075.html", "https://bugzilla.redhat.com/show_bug.cgi?id=1500742", "https://docs.saltstack.com/en/latest/topics/releases/2017.7.2.html" ], "severity": "Medium" } ] assert_equal(results.get('details'), expected_details)