mirror of
https://github.com/Security-Onion-Solutions/securityonion.git
synced 2025-12-06 17:22:49 +01:00
Merge pull request #7936 from Security-Onion-Solutions/kilo
Improved unit test coverage of new analyzers; Utilize localized summa…
This commit is contained in:
2
.github/workflows/pythontest.yml
vendored
2
.github/workflows/pythontest.yml
vendored
@@ -28,4 +28,4 @@ jobs:
|
|||||||
flake8 ${{ matrix.python-code-path }} --show-source --max-complexity=12 --doctests --max-line-length=200 --statistics
|
flake8 ${{ matrix.python-code-path }} --show-source --max-complexity=12 --doctests --max-line-length=200 --statistics
|
||||||
- name: Test with pytest
|
- name: Test with pytest
|
||||||
run: |
|
run: |
|
||||||
pytest ${{ matrix.python-code-path }} --cov=${{ matrix.python-code-path }} --doctest-modules --cov-report=term --cov-fail-under=90 --cov-config=${{ matrix.python-code-path }}/pytest.ini
|
pytest ${{ matrix.python-code-path }} --cov=${{ matrix.python-code-path }} --doctest-modules --cov-report=term --cov-fail-under=100 --cov-config=${{ matrix.python-code-path }}/pytest.ini
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ def prepareResults(raw):
|
|||||||
elif "status" in raw:
|
elif "status" in raw:
|
||||||
if raw["reason"] == "invalid email":
|
if raw["reason"] == "invalid email":
|
||||||
status = "caution"
|
status = "caution"
|
||||||
summary = "Invalid email address."
|
summary = "invalid_input"
|
||||||
if "exceeded daily limit" in raw["reason"]:
|
if "exceeded daily limit" in raw["reason"]:
|
||||||
status = "caution"
|
status = "caution"
|
||||||
summary = "Exceeded daily request limit."
|
summary = "excessive_usage"
|
||||||
else:
|
else:
|
||||||
status = "caution"
|
status = "caution"
|
||||||
summary = "internal_failure"
|
summary = "internal_failure"
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class TestEmailRepMethods(unittest.TestCase):
|
|||||||
raw = {"status": "fail", "reason": "invalid email"}
|
raw = {"status": "fail", "reason": "invalid email"}
|
||||||
results = emailrep.prepareResults(raw)
|
results = emailrep.prepareResults(raw)
|
||||||
self.assertEqual(results["response"], raw)
|
self.assertEqual(results["response"], raw)
|
||||||
self.assertEqual(results["summary"], "Invalid email address.")
|
self.assertEqual(results["summary"], "invalid_input")
|
||||||
self.assertEqual(results["status"], "caution")
|
self.assertEqual(results["status"], "caution")
|
||||||
|
|
||||||
def test_prepareResults_not_suspicious(self):
|
def test_prepareResults_not_suspicious(self):
|
||||||
@@ -65,7 +65,7 @@ class TestEmailRepMethods(unittest.TestCase):
|
|||||||
raw = {"status": "fail", "reason": "exceeded daily limit. please wait 24 hrs or visit emailrep.io/key for an api key."}
|
raw = {"status": "fail", "reason": "exceeded daily limit. please wait 24 hrs or visit emailrep.io/key for an api key."}
|
||||||
results = emailrep.prepareResults(raw)
|
results = emailrep.prepareResults(raw)
|
||||||
self.assertEqual(results["response"], raw)
|
self.assertEqual(results["response"], raw)
|
||||||
self.assertEqual(results["summary"], "Exceeded daily request limit.")
|
self.assertEqual(results["summary"], "excessive_usage")
|
||||||
self.assertEqual(results["status"], "caution")
|
self.assertEqual(results["status"], "caution")
|
||||||
|
|
||||||
def test_prepareResults_error(self):
|
def test_prepareResults_error(self):
|
||||||
|
|||||||
@@ -36,13 +36,13 @@ def prepareResults(raw):
|
|||||||
summary = "malicious"
|
summary = "malicious"
|
||||||
elif "unknown" in raw['classification']:
|
elif "unknown" in raw['classification']:
|
||||||
status = "caution"
|
status = "caution"
|
||||||
summary = "Results found."
|
summary = "suspicious"
|
||||||
elif "IP not observed scanning the internet or contained in RIOT data set." in raw["message"]:
|
elif "IP not observed scanning the internet or contained in RIOT data set." in raw["message"]:
|
||||||
status = "ok"
|
status = "ok"
|
||||||
summary = "no_results"
|
summary = "no_results"
|
||||||
elif "Request is not a valid routable IPv4 address" in raw["message"]:
|
elif "Request is not a valid routable IPv4 address" in raw["message"]:
|
||||||
status = "caution"
|
status = "caution"
|
||||||
summary = "Invalid IP address."
|
summary = "invalid_input"
|
||||||
else:
|
else:
|
||||||
status = "info"
|
status = "info"
|
||||||
summary = raw["message"]
|
summary = raw["message"]
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ class TestGreynoiseMethods(unittest.TestCase):
|
|||||||
raw = {"message": "Request is not a valid routable IPv4 address"}
|
raw = {"message": "Request is not a valid routable IPv4 address"}
|
||||||
results = greynoise.prepareResults(raw)
|
results = greynoise.prepareResults(raw)
|
||||||
self.assertEqual(results["response"], raw)
|
self.assertEqual(results["response"], raw)
|
||||||
self.assertEqual(results["summary"], "Invalid IP address.")
|
self.assertEqual(results["summary"], "invalid_input")
|
||||||
self.assertEqual(results["status"], "caution")
|
self.assertEqual(results["status"], "caution")
|
||||||
|
|
||||||
def test_prepareResults_not_found(self):
|
def test_prepareResults_not_found(self):
|
||||||
@@ -90,7 +90,7 @@ class TestGreynoiseMethods(unittest.TestCase):
|
|||||||
raw = {"ip": "221.4.62.149", "noise": "true", "riot": "false", "classification": "unknown", "name": "unknown", "link": "https://viz.gn.io", "last_seen": "2022-04-26", "message": "Success"}
|
raw = {"ip": "221.4.62.149", "noise": "true", "riot": "false", "classification": "unknown", "name": "unknown", "link": "https://viz.gn.io", "last_seen": "2022-04-26", "message": "Success"}
|
||||||
results = greynoise.prepareResults(raw)
|
results = greynoise.prepareResults(raw)
|
||||||
self.assertEqual(results["response"], raw)
|
self.assertEqual(results["response"], raw)
|
||||||
self.assertEqual(results["summary"], "Results found.")
|
self.assertEqual(results["summary"], "suspicious")
|
||||||
self.assertEqual(results["status"], "caution")
|
self.assertEqual(results["status"], "caution")
|
||||||
|
|
||||||
def test_prepareResults_unknown_message(self):
|
def test_prepareResults_unknown_message(self):
|
||||||
@@ -113,5 +113,5 @@ class TestGreynoiseMethods(unittest.TestCase):
|
|||||||
conf = {"base_url": "myurl/", "api_key": "abcd1234", "api_version": "community"}
|
conf = {"base_url": "myurl/", "api_key": "abcd1234", "api_version": "community"}
|
||||||
with patch('greynoise.greynoise.sendReq', new=MagicMock(return_value=output)) as mock:
|
with patch('greynoise.greynoise.sendReq', new=MagicMock(return_value=output)) as mock:
|
||||||
results = greynoise.analyze(conf, artifactInput)
|
results = greynoise.analyze(conf, artifactInput)
|
||||||
self.assertEqual(results["summary"], "Results found.")
|
self.assertEqual(results["summary"], "suspicious")
|
||||||
mock.assert_called_once()
|
mock.assert_called_once()
|
||||||
|
|||||||
@@ -15,16 +15,16 @@ def prepareResults(raw):
|
|||||||
if "error" in raw:
|
if "error" in raw:
|
||||||
if "Sorry" in raw["error"]:
|
if "Sorry" in raw["error"]:
|
||||||
status = "ok"
|
status = "ok"
|
||||||
summary = "No results found."
|
summary = "no_results"
|
||||||
elif "Invalid hash" in raw["error"]:
|
elif "Invalid hash" in raw["error"]:
|
||||||
status = "caution"
|
status = "caution"
|
||||||
summary = "Invalid hash."
|
summary = "invalid_input"
|
||||||
else:
|
else:
|
||||||
status = "caution"
|
status = "caution"
|
||||||
summary = "internal_failure"
|
summary = "internal_failure"
|
||||||
else:
|
else:
|
||||||
status = "info"
|
status = "info"
|
||||||
summary = "Results found."
|
summary = "suspicious"
|
||||||
results = {'response': raw, 'summary': summary, 'status': status}
|
results = {'response': raw, 'summary': summary, 'status': status}
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
|||||||
@@ -38,21 +38,28 @@ class TestJa3erMethods(unittest.TestCase):
|
|||||||
raw = {"error": "Sorry no values found"}
|
raw = {"error": "Sorry no values found"}
|
||||||
results = ja3er.prepareResults(raw)
|
results = ja3er.prepareResults(raw)
|
||||||
self.assertEqual(results["response"], raw)
|
self.assertEqual(results["response"], raw)
|
||||||
self.assertEqual(results["summary"], "No results found.")
|
self.assertEqual(results["summary"], "no_results")
|
||||||
self.assertEqual(results["status"], "ok")
|
self.assertEqual(results["status"], "ok")
|
||||||
|
|
||||||
def test_prepareResults_invalidHash(self):
|
def test_prepareResults_invalidHash(self):
|
||||||
raw = {"error": "Invalid hash"}
|
raw = {"error": "Invalid hash"}
|
||||||
results = ja3er.prepareResults(raw)
|
results = ja3er.prepareResults(raw)
|
||||||
self.assertEqual(results["response"], raw)
|
self.assertEqual(results["response"], raw)
|
||||||
self.assertEqual(results["summary"], "Invalid hash.")
|
self.assertEqual(results["summary"], "invalid_input")
|
||||||
|
self.assertEqual(results["status"], "caution")
|
||||||
|
|
||||||
|
def test_prepareResults_internal_failure(self):
|
||||||
|
raw = {"error": "unknown"}
|
||||||
|
results = ja3er.prepareResults(raw)
|
||||||
|
self.assertEqual(results["response"], raw)
|
||||||
|
self.assertEqual(results["summary"], "internal_failure")
|
||||||
self.assertEqual(results["status"], "caution")
|
self.assertEqual(results["status"], "caution")
|
||||||
|
|
||||||
def test_prepareResults_info(self):
|
def test_prepareResults_info(self):
|
||||||
raw = [{"User-Agent": "Blah/5.0", "Count": 24874, "Last_seen": "2022-04-08 16:18:38"}, {"Comment": "Brave browser v1.36.122\n\n", "Reported": "2022-03-28 20:26:42"}]
|
raw = [{"User-Agent": "Blah/5.0", "Count": 24874, "Last_seen": "2022-04-08 16:18:38"}, {"Comment": "Brave browser v1.36.122\n\n", "Reported": "2022-03-28 20:26:42"}]
|
||||||
results = ja3er.prepareResults(raw)
|
results = ja3er.prepareResults(raw)
|
||||||
self.assertEqual(results["response"], raw)
|
self.assertEqual(results["response"], raw)
|
||||||
self.assertEqual(results["summary"], "Results found.")
|
self.assertEqual(results["summary"], "suspicious")
|
||||||
self.assertEqual(results["status"], "info")
|
self.assertEqual(results["status"], "info")
|
||||||
|
|
||||||
def test_analyze(self):
|
def test_analyze(self):
|
||||||
@@ -61,5 +68,5 @@ class TestJa3erMethods(unittest.TestCase):
|
|||||||
conf = {"base_url": "myurl/"}
|
conf = {"base_url": "myurl/"}
|
||||||
with patch('ja3er.ja3er.sendReq', new=MagicMock(return_value=output)) as mock:
|
with patch('ja3er.ja3er.sendReq', new=MagicMock(return_value=output)) as mock:
|
||||||
results = ja3er.analyze(conf, artifactInput)
|
results = ja3er.analyze(conf, artifactInput)
|
||||||
self.assertEqual(results["summary"], "Results found.")
|
self.assertEqual(results["summary"], "suspicious")
|
||||||
mock.assert_called_once()
|
mock.assert_called_once()
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ def prepareResults(raw):
|
|||||||
summary = "no_results"
|
summary = "no_results"
|
||||||
else:
|
else:
|
||||||
status = "info"
|
status = "info"
|
||||||
summary = "One or more matches found."
|
summary = "suspicious"
|
||||||
else:
|
else:
|
||||||
raw = {}
|
raw = {}
|
||||||
status = "caution"
|
status = "caution"
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ class TestLocalfileMethods(unittest.TestCase):
|
|||||||
]
|
]
|
||||||
results = localfile.prepareResults(raw)
|
results = localfile.prepareResults(raw)
|
||||||
self.assertEqual(results["response"], raw)
|
self.assertEqual(results["response"], raw)
|
||||||
self.assertEqual(results["summary"], "One or more matches found.")
|
self.assertEqual(results["summary"], "suspicious")
|
||||||
self.assertEqual(results["status"], "info")
|
self.assertEqual(results["status"], "info")
|
||||||
|
|
||||||
def test_prepareResults_error(self):
|
def test_prepareResults_error(self):
|
||||||
@@ -115,5 +115,5 @@ class TestLocalfileMethods(unittest.TestCase):
|
|||||||
conf = {"file_path": "/home/intel.csv"}
|
conf = {"file_path": "/home/intel.csv"}
|
||||||
with patch('localfile.localfile.searchFile', new=MagicMock(return_value=output)) as mock:
|
with patch('localfile.localfile.searchFile', new=MagicMock(return_value=output)) as mock:
|
||||||
results = localfile.analyze(conf, artifactInput)
|
results = localfile.analyze(conf, artifactInput)
|
||||||
self.assertEqual(results["summary"], "One or more matches found.")
|
self.assertEqual(results["summary"], "suspicious")
|
||||||
mock.assert_called_once()
|
mock.assert_called_once()
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ def prepareResults(response):
|
|||||||
summaryinfo = "harmless"
|
summaryinfo = "harmless"
|
||||||
elif reputation > 0 and reputation < 50:
|
elif reputation > 0 and reputation < 50:
|
||||||
status = "ok"
|
status = "ok"
|
||||||
summaryinfo = "Likely Harmless"
|
summaryinfo = "likely_harmless"
|
||||||
elif reputation >= 50 and reputation < 75:
|
elif reputation >= 50 and reputation < 75:
|
||||||
status = "caution"
|
status = "caution"
|
||||||
summaryinfo = "suspicious"
|
summaryinfo = "suspicious"
|
||||||
@@ -53,7 +53,7 @@ def prepareResults(response):
|
|||||||
summaryinfo = "malicious"
|
summaryinfo = "malicious"
|
||||||
else:
|
else:
|
||||||
status = "info"
|
status = "info"
|
||||||
summaryinfo = "Analysis complete."
|
summaryinfo = "analyzer_analysis_complete"
|
||||||
else:
|
else:
|
||||||
raw = {}
|
raw = {}
|
||||||
status = "caution"
|
status = "caution"
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class TestOtxMethods(unittest.TestCase):
|
|||||||
self.assertEqual(mock_stdout.getvalue(), expected)
|
self.assertEqual(mock_stdout.getvalue(), expected)
|
||||||
mock.assert_called_once()
|
mock.assert_called_once()
|
||||||
|
|
||||||
def checkConfigRequirements(self):
|
def test_checkConfigRequirements(self):
|
||||||
conf = {"not_a_key": "abcd12345"}
|
conf = {"not_a_key": "abcd12345"}
|
||||||
with self.assertRaises(SystemExit) as cm:
|
with self.assertRaises(SystemExit) as cm:
|
||||||
otx.checkConfigRequirements(conf)
|
otx.checkConfigRequirements(conf)
|
||||||
@@ -119,7 +119,7 @@ class TestOtxMethods(unittest.TestCase):
|
|||||||
}
|
}
|
||||||
results = otx.prepareResults(raw)
|
results = otx.prepareResults(raw)
|
||||||
self.assertEqual(results["response"], raw)
|
self.assertEqual(results["response"], raw)
|
||||||
self.assertEqual(results["summary"], "Likely Harmless")
|
self.assertEqual(results["summary"], "likely_harmless")
|
||||||
self.assertEqual(results["status"], "ok")
|
self.assertEqual(results["status"], "ok")
|
||||||
|
|
||||||
def test_prepareResults_suspicious(self):
|
def test_prepareResults_suspicious(self):
|
||||||
@@ -210,7 +210,7 @@ class TestOtxMethods(unittest.TestCase):
|
|||||||
}
|
}
|
||||||
results = otx.prepareResults(raw)
|
results = otx.prepareResults(raw)
|
||||||
self.assertEqual(results["response"], raw)
|
self.assertEqual(results["response"], raw)
|
||||||
self.assertEqual(results["summary"], "Analysis complete.")
|
self.assertEqual(results["summary"], "analyzer_analysis_complete")
|
||||||
self.assertEqual(results["status"], "info")
|
self.assertEqual(results["status"], "info")
|
||||||
|
|
||||||
def test_prepareResults_error(self):
|
def test_prepareResults_error(self):
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ def prepareResults(raw):
|
|||||||
summary = "suspicious"
|
summary = "suspicious"
|
||||||
else:
|
else:
|
||||||
status = "info"
|
status = "info"
|
||||||
summary = "Scan complete."
|
summary = "analysis_complete"
|
||||||
else:
|
else:
|
||||||
status = "caution"
|
status = "caution"
|
||||||
summary = "internal_failure"
|
summary = "internal_failure"
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ class TestUrlScanMethods(unittest.TestCase):
|
|||||||
raw = {"requests": [{"request": {"requestId": "3"}}], "verdicts": {"overall": {"score": 0, "malicious": False, "hasVerdicts": False}}}
|
raw = {"requests": [{"request": {"requestId": "3"}}], "verdicts": {"overall": {"score": 0, "malicious": False, "hasVerdicts": False}}}
|
||||||
results = urlscan.prepareResults(raw)
|
results = urlscan.prepareResults(raw)
|
||||||
self.assertEqual(results["response"], raw)
|
self.assertEqual(results["response"], raw)
|
||||||
self.assertEqual(results["summary"], "Scan complete.")
|
self.assertEqual(results["summary"], "analysis_complete")
|
||||||
self.assertEqual(results["status"], "info")
|
self.assertEqual(results["status"], "info")
|
||||||
|
|
||||||
def test_prepareResults_error(self):
|
def test_prepareResults_error(self):
|
||||||
@@ -116,6 +116,6 @@ class TestUrlScanMethods(unittest.TestCase):
|
|||||||
with patch('urlscan.urlscan.sendReq', new=MagicMock(return_value=output_req)) as mock_req:
|
with patch('urlscan.urlscan.sendReq', new=MagicMock(return_value=output_req)) as mock_req:
|
||||||
with patch('urlscan.urlscan.getReport', new=MagicMock(return_value=output_report)) as mock_report:
|
with patch('urlscan.urlscan.getReport', new=MagicMock(return_value=output_report)) as mock_report:
|
||||||
results = urlscan.analyze(conf, artifactInput)
|
results = urlscan.analyze(conf, artifactInput)
|
||||||
self.assertEqual(results["summary"], "Scan complete.")
|
self.assertEqual(results["summary"], "analysis_complete")
|
||||||
mock_req.assert_called_once()
|
mock_req.assert_called_once()
|
||||||
mock_report.assert_called_once()
|
mock_report.assert_called_once()
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class TestVirusTotalMethods(unittest.TestCase):
|
|||||||
self.assertEqual(mock_stdout.getvalue(), expected)
|
self.assertEqual(mock_stdout.getvalue(), expected)
|
||||||
mock.assert_called_once()
|
mock.assert_called_once()
|
||||||
|
|
||||||
def checkConfigRequirements(self):
|
def test_checkConfigRequirements(self):
|
||||||
conf = {"not_a_key": "abcd12345"}
|
conf = {"not_a_key": "abcd12345"}
|
||||||
with self.assertRaises(SystemExit) as cm:
|
with self.assertRaises(SystemExit) as cm:
|
||||||
virustotal.checkConfigRequirements(conf)
|
virustotal.checkConfigRequirements(conf)
|
||||||
|
|||||||
Reference in New Issue
Block a user