"""Base Integration for Cortex XSOAR - Unit Tests file Pytest Unit Tests: all funcion names must start with "test_" More details: https://xsoar.pan.dev/docs/integrations/unit-testing MAKE SURE YOU REVIEW/REPLACE ALL THE COMMENTS MARKED AS "TODO" You must add at least a Unit Test function for every XSOAR command you are implementing with your integration """ import json import unittest from unittest import mock from ExodusVulnerabilityEnrichment import ( connect, extract_data, fetch_indicators, get_best_xi_score, reset_data_stream, ) RESET = {"data": {"end_ts": "2022-06-09T06:38:01.373000", "items": []}} VULN = { "data": { "access_vector": "remote", "attack_vector": "NETWORK", "cpes": [{"children": [], "cpe_match": [], "operator": "OR"}], "created_timestamp": "Thu, 15 Apr 2021 06:07:52 GMT", "cves": ["CVE-2021-28482"], "cvss": 8.8, "description": "Microsoft Exchange Server Remote Code Execution.", "identifier": "XI-00053139", "modified_timestamp": "2022-03-18T12:20:27.474000", "product": "Microsoft Exchange Server 2019 Cumulative Update 8", "publish_date": "2021-04-13T00:00:00", "reported": False, "updated_date": "2021-04-13T00:00:00", "vendor": "Microsoft", "xi_scores": [ {"comment": "", "created_at": "April-09-2022", "score": 4.85}, { "comment": "Public POC: https://gist.github.com/testanull/9ebbd6830f7a501e35e67f2fcaa57bda", "created_at": "June-17-2021", "score": 8.4, }, ], "zdis": [], }, "ok": True, } VULNS = { "data": { "end_ts": "2022-06-18T07:31:40.435000", "items": [ { "cpes": None, "created_timestamp": "2022-06-17T06:02:29.714000", "cves": ["CVE-2022-21166"], "cvss": None, "description": "Incomplete cleanup in specific special.", "identifier": "XI-00074894", "modified_timestamp": "2022-06-18T07:21:52.386000", "product": "Intel(R) Processors", "publish_date": "2022-06-15T00:00:00", "updated_date": "2022-06-15T00:00:00", "vendor": "n/a", "xi_scores": [ { "comment": "", "created_at": "2022-06-17T06:02:29.809188", "score": 6.02, } ], "zdis": [], }, { "cpes": None, "created_timestamp": "2022-05-16T21:41:41.296000", "cves": ["CVE-2022-30129"], "cvss": 8.8, "description": "Visual Studio Code Remote Code Execution Vulnerability.", "identifier": "XI-00072972", "modified_timestamp": "2022-06-18T07:31:02.331000", "product": "Visual Studio Code", "publish_date": "2022-05-10T00:00:00", "updated_date": "2022-05-10T00:00:00", "vendor": "Microsoft", "xi_scores": [ { "comment": "", "created_at": "2022-05-16T21:41:41.346977", "score": 4.0600000000000005, } ], "zdis": [], }, { "cpes": None, "created_timestamp": "2022-06-08T17:43:52.541000", "cves": ["CVE-2022-30787"], "cvss": None, "description": "An integer underflow in fuse_lib_readdir enables arbitrary.", "identifier": "XI-00073958", "modified_timestamp": "2022-06-18T07:31:40.435000", "product": "n/a", "publish_date": "2022-05-26T00:00:00", "updated_date": "2022-05-26T00:00:00", "vendor": "n/a", "xi_scores": [ { "comment": "", "created_at": "2022-06-09T06:02:50.723589", "score": 5.200000000000001, } ], "zdis": [], }, ], }, "errmsg": None, "ok": True, } VULNS_E = { "data": { "end_ts": "2022-06-18T07:31:40.435000", "items": [ { "cpes": None, "created_timestamp": "2022-06-17T06:02:29.714000", "cves": ["CVE-2022-21166"], "cvss": None, "description": "Incomplete cleanup in specific special.", "identifier": "XI-00074894", "modified_timestamp": "2022-06-18T07:21:52.386000", "product": "Intel(R) Processors", "publish_date": "2022-06-15T00:00:00", "updated_date": "2022-06-15T00:00:00", "vendor": "n/a", "xi_scores": [ { "comment": "", "created_at": "2022-06-17T06:02:29.809188", "score": 6.02, } ], "zdis": [], }, { "cpes": None, "created_timestamp": "2022-05-16T21:41:41.296000", "cves": ["CVE-2022-30129"], "cvss": 8.8, "description": "Visual Studio Code Remote Code Execution Vulnerability.", "identifier": "XI-00072972", "modified_timestamp": "2022-06-18T07:31:02.331000", "product": "Visual Studio Code", "publish_date": "2022-05-10T00:00:00", "updated_date": "2022-05-10T00:00:00", "vendor": "Microsoft", "xi_scores": [ { "comment": "", "created_at": "2022-05-16T21:41:41.346977", "score": 4.0600000000000005, } ], "zdis": [], }, { "cpes": None, "created_timestamp": "2022-06-08T17:43:52.541000", "cves": ["CVE-2022-30787"], "cvss": None, "description": "An integer underflow in fuse_lib_readdir enables arbitrary.", "identifier": "XI-00073958", "modified_timestamp": "2022-06-18T07:31:40.435000", "product": "n/a", "publish_date": "2022-05-26T00:00:00", "updated_date": "2022-05-26T00:00:00", "vendor": "n/a", "xi_scores": [ { "comment": "", "created_at": "2022-06-09T06:02:50.723589", "score": 5.200000000000001, } ], "zdis": [], }, ], }, "errmsg": None, "ok": True, } def util_load_json(path): with open(path, encoding="utf-8") as f: return json.loads(f.read()) class MyTestsCase(unittest.TestCase): @mock.patch("ExodusVulnerabilityEnrichment.eve.EVEClient", autospec=True) def test_connect(self, m_eve): m_eve.return_value = mock.Mock() connect("abc@abc.com", "PASSWORD", "CLIENT_ENCRYPTION_KEY", "EVE_URL") m_eve.side_effect = ConnectionError with self.assertRaises(ConnectionError): connect("abc@abc.com", "PASSWORD", "CLIENT_ENCRYPTION_KEY", "EVE_URL") @mock.patch("ExodusVulnerabilityEnrichment.connect", autospec=True) def test_fetch_indicators(self, m_connect): instance = m_connect.return_value instance.get_recent_vulns.return_value = VULN fetch_indicators("abc@abc.com", "PASSWORD", "CLIENT_ENCRYPTION_KEY", "EVE_URL", 10, 0) instance.get_recent_vulns.return_value = VULNS fetch_indicators("abc@abc.com", "PASSWORD", "CLIENT_ENCRYPTION_KEY", "EVE_URL", 10, 0) instance.get_recent_vulns.return_value = VULNS_E fetch_indicators("abc@abc.com", "PASSWORD", "CLIENT_ENCRYPTION_KEY", "EVE_URL", 10, 0) @mock.patch("ExodusVulnerabilityEnrichment.connect", autospec=True) def test_reset_data_stream(self, m_connect): instance = m_connect.return_value instance.get_recent_vulns.return_value = RESET reset_data_stream("abc@abc.com", "PASSWORD", "CLIENT_ENCRYPTION_KEY", "EVE_URL", 10) instance.get_recent_vulns.side_effect = ConnectionError with self.assertRaises(ConnectionError): reset_data_stream("abc@abc.com", "PASSWORD", "CLIENT_ENCRYPTION_KEY", "EVE_URL", 10) def test_get_best_xi_scores(self): comments = [ { "comment": "", "created_at": "2022-06-17T06:02:28.774560", "score": 5.91, }, { "comment": "Human", "created_at": "2022-06-17T06:02:28.774560", "score": 5.96, }, ] data = get_best_xi_score(comments) assert data == 5.96 comments = [] data = get_best_xi_score(comments) assert data == 0.0 def test_extract_data(self): CLEAN_DATA = { "xicve": "CVE-2021-28482", "xiidentifier": "XI-00053139", "xiattackvector": "NETWORK", "xicvss": 8.8, "xidescription": "Microsoft Exchange Server Remote Code Execution.", "ximodifiedtimestamp": "2022-03-18T12:20:27.474000", "xiproduct": "Microsoft Exchange Server 2019 Cumulative Update 8", "xipublishdate": "2021-04-13T00:00:00", "xivendor": "Microsoft", "xiscores": 8.4, } report_data = {"xicve": "CVE-2021-28482", "xiidentifier": "XI-00053139"} data = extract_data(VULN, report_data) assert data == CLEAN_DATA data = {"transport": [1, 2, 3], "links": "123"} extract_data(data, {}) data = {"transport": "", "links": "123"} extract_data(data, {})