aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/test_parse.py63
1 files changed, 63 insertions, 0 deletions
diff --git a/tests/test_parse.py b/tests/test_parse.py
index 0fac304..28c8609 100644
--- a/tests/test_parse.py
+++ b/tests/test_parse.py
@@ -157,5 +157,68 @@ class TestAttachments(unittest.TestCase):
self.assertEqual(parse.attachments(load("simple.eml")), [])
+class TestIocAssembly(unittest.TestCase):
+ def test_every_ioc_has_a_unique_id_and_an_origin(self):
+ iocs = parse.iocs(load("simple.eml"), trusted=["192.0.2.0/24"])
+ ids = [i["id"] for i in iocs]
+ self.assertEqual(len(ids), len(set(ids)))
+ self.assertTrue(all(i["origin"] for i in iocs))
+
+ def test_the_sending_ip_is_present_and_marked_boundary_hop(self):
+ iocs = parse.iocs(load("simple.eml"), trusted=["192.0.2.0/24"])
+ ips = [i for i in iocs if i["type"] == "ipv4"]
+ self.assertEqual(ips[0]["value"], "203.0.113.42")
+ self.assertEqual(ips[0]["confidence"], "boundary-hop")
+
+ def test_hops_below_the_boundary_are_marked_untrusted(self):
+ iocs = parse.iocs(load("forged-chain.eml"), trusted=["192.0.2.0/24"])
+ ips = {i["value"]: i for i in iocs if i["type"] == "ipv4"}
+ self.assertEqual(ips["203.0.113.99"]["confidence"], "boundary-hop")
+ self.assertEqual(ips["198.51.100.7"]["confidence"], "untrusted-hop")
+
+ def test_our_own_relays_are_not_reported_as_indicators(self):
+ # Inside the boundary is our own infrastructure, not an indicator.
+ iocs = parse.iocs(load("forged-chain.eml"), trusted=["192.0.2.0/24"])
+ values = [i["value"] for i in iocs]
+ self.assertNotIn("192.0.2.11", values)
+
+ def test_urls_carry_their_redacted_form(self):
+ iocs = parse.iocs(load("simple.eml"), trusted=["192.0.2.0/24"])
+ urls = [i for i in iocs if i["type"] == "url"]
+ self.assertEqual(len(urls), 1)
+ self.assertIn("REDACTED", urls[0]["value"])
+
+ def test_a_suspect_path_segment_is_flagged_on_the_ioc(self):
+ iocs = parse.iocs(load("simple.eml"), trusted=["192.0.2.0/24"])
+ url = next(i for i in iocs if i["type"] == "url")
+ self.assertEqual(url["suspect_path_segments"], ["dGVzdEBleGFtcGxlLm9yZw"])
+
+ def test_a_redirect_target_is_its_own_ioc(self):
+ iocs = parse.iocs(load("redirector.eml"), trusted=["192.0.2.0/24"])
+ targets = [i for i in iocs if i["origin"] == "redirect-target"]
+ self.assertEqual(len(targets), 1)
+ self.assertEqual(targets[0]["value"],
+ "http://evil.example.invalid/pay?ref=REDACTED")
+
+ def test_an_attachment_becomes_a_hash_ioc(self):
+ iocs = parse.iocs(load("with-attachment.eml"), trusted=["192.0.2.0/24"])
+ hashes = [i for i in iocs if i["type"] == "sha256"]
+ self.assertEqual(len(hashes), 1)
+ self.assertEqual(hashes[0]["filename"], "invoice.pdf")
+
+ def test_no_trusted_relays_still_refuses(self):
+ with self.assertRaises(parse.NoTrustBoundary):
+ parse.iocs(load("simple.eml"), trusted=[])
+
+ def test_no_ioc_holds_a_recipient_address(self):
+ # The safety property, asserted over the whole output.
+ for name in ("simple.eml", "forged-chain.eml", "with-attachment.eml",
+ "redirector.eml"):
+ iocs = parse.iocs(load(name), trusted=["192.0.2.0/24"])
+ blob = repr(iocs)
+ self.assertNotIn("you@example.org", blob)
+ self.assertNotIn("example.org", blob)
+
+
if __name__ == "__main__":
unittest.main()