Skip to content

Commit

Permalink
Merge pull request #198 from chrisr3d/master
Browse files Browse the repository at this point in the history
Fixed timestamp fields comparison
  • Loading branch information
adulau authored Apr 8, 2024
2 parents 92de569 + 2133fbe commit 963af14
Show file tree
Hide file tree
Showing 37 changed files with 623 additions and 60 deletions.
6 changes: 6 additions & 0 deletions stix2validator/test/v20/attack_pattern_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,9 @@ def test_invalid_timestamp(self):

attack_pattern['modified'] = "2016-02-29T08:17:27.000Z"
self.assertTrueWithOptions(attack_pattern)

attack_pattern['created'] = "2016-02-29T08:17:27.123Z"
self.assertFalseWithOptions(attack_pattern)

attack_pattern['modified'] = "2016-02-29T08:17:27.123Z"
self.assertTrueWithOptions(attack_pattern)
52 changes: 52 additions & 0 deletions stix2validator/test/v20/campaign_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import copy
import json

from . import ValidatorTest
from ... import validate_string

VALID_CAMPAIGN = u"""
{
"type": "campaign",
"id": "campaign--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061",
"created": "2023-03-17T13:37:42.596Z",
"modified": "2023-09-27T20:12:54.984Z",
"created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff",
"name": "Operation Dream Job",
"description": "Operation Dream Job was a cyber espionage operation likely conducted by Lazarus Group.",
"aliases": [
"Operation Dream Job",
"Operation North Star",
"Operation Interception"
],
"first_seen": "2019-09-01T04:00:00.000Z",
"last_seen": "2020-08-01T04:00:00.000Z"
}
"""


class CampaignTestCases(ValidatorTest):
valid_campaign = json.loads(VALID_CAMPAIGN)

def test_wellformed_campaign(self):
results = validate_string(VALID_CAMPAIGN, self.options)
self.assertTrue(results.is_valid)

def test_invalid_timestamp(self):
campaign = copy.deepcopy(self.valid_campaign)
campaign['created'] = "2016-09-31T08:17:27.000Z"
self.assertFalseWithOptions(campaign)

campaign['created'] = "2023-09-27T20:12:54.985Z"
self.assertFalseWithOptions(campaign)

campaign['modified'] = "2023-09-27T20:12:54.985Z"
self.assertTrueWithOptions(campaign)

campaign['first_seen'] = "2019-09-31T04:00:00.000Z"
self.assertFalseWithOptions(campaign)

campaign['first_seen'] = "2020-08-01T04:00:00.001Z"
self.assertFalseWithOptions(campaign)

campaign['last_seen'] = "2020-08-01T04:00:00.001Z"
self.assertTrueWithOptions(campaign)
36 changes: 36 additions & 0 deletions stix2validator/test/v20/coa_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import copy
import json

from . import ValidatorTest
from ... import validate_string

VALID_COURSE_OF_ACTION = u"""
{
"type": "course-of-action",
"id": "course-of-action--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f",
"created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff",
"created": "2016-04-06T20:03:48.000Z",
"modified": "2016-04-06T20:03:48.000Z",
"name": "mitigation-poison-ivy-firewall",
"description": "Recommended steps to respond to the Poison Ivy malware"
}
"""


class CoATestCases(ValidatorTest):
valid_course_of_action = json.loads(VALID_COURSE_OF_ACTION)

def test_wellformed_coa(self):
results = validate_string(VALID_COURSE_OF_ACTION, self.options)
self.assertTrue(results.is_valid)

def test_invalid_timestamp(self):
coa = copy.deepcopy(self.valid_course_of_action)
coa['created'] = "2016-11-31T01:00:00.000Z"
self.assertFalseWithOptions(coa)

coa['created'] = "2016-04-06T20:03:48.123Z"
self.assertFalseWithOptions(coa)

coa['modified'] = "2016-04-06T20:03:48.123Z"
self.assertTrueWithOptions(coa)
11 changes: 11 additions & 0 deletions stix2validator/test/v20/custom_obj_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,17 @@ def test_no_modified(self):
results = validate_parsed_json(custom_obj, self.options)
self.assertEqual(results.is_valid, False)

def test_invalid_timestamp(self):
custom_object = copy.deepcopy(self.valid_custom_object)
custom_object['created'] = "2016-11-31T01:00:00.000Z"
self.assertFalseWithOptions(custom_object)

custom_object['created'] = "2016-08-01T01:00:01.000Z"
self.assertFalseWithOptions(custom_object)

custom_object['modified'] = "2016-08-01T01:00:01.000Z"
self.assertTrueWithOptions(custom_object)

def test_invalid_type_name(self):
custom_obj = copy.deepcopy(self.valid_custom_object)
custom_obj['type'] = "corpo_ration"
Expand Down
11 changes: 11 additions & 0 deletions stix2validator/test/v20/identity_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ def test_invalid_check(self):
self.assertRaises(exceptions.ValidationError, self.assertFalseWithOptions,
self.valid_identity, enabled='abc')

def test_invalid_timestamp(self):
identity = copy.deepcopy(self.valid_identity)
identity['created'] = "2014-13-08T15:50:10.983Z"
self.assertFalseWithOptions(identity)

identity['created'] = "2014-08-08T15:50:10.984Z"
self.assertFalseWithOptions(identity)

identity['modified'] = "2014-08-08T15:50:10.984Z"
self.assertTrueWithOptions(identity)

def test_wellformed_identity(self):
results = validate_string(VALID_IDENTITY, self.options)
self.assertTrue(results.is_valid)
Expand Down
22 changes: 18 additions & 4 deletions stix2validator/test/v20/indicator_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,25 @@ def test_wellformed_indicator(self):
results = validate_string(VALID_INDICATOR, self.options)
self.assertTrue(results.is_valid)

def test_modified_before_created(self):
def test_invalid_timestamp(self):
indicator = copy.deepcopy(self.valid_indicator)
indicator['modified'] = "2001-04-06T20:03:48Z"
results = validate_parsed_json(indicator, self.options)
self.assertEqual(results.is_valid, False)
indicator['created'] = "2016-11-31T20:03:48.000Z"
self.assertFalseWithOptions(indicator)

indicator['created'] = "2016-04-06T20:03:48.001Z"
self.assertFalseWithOptions(indicator)

indicator['modified'] = "2016-04-06T20:03:48.001Z"
self.assertTrueWithOptions(indicator)

indicator['valid_until'] = "2016-11-31T20:03:48.000Z"
self.assertFalseWithOptions(indicator)

indicator['valid_until'] = "2016-04-06T20:03:48.001Z"
self.assertTrueWithOptions(indicator)

indicator['valid_from'] = "2016-04-06T20:03:48.002Z"
self.assertFalseWithOptions(indicator)

def test_custom_property_name_invalid_character(self):
indicator = copy.deepcopy(self.valid_indicator)
Expand Down
21 changes: 21 additions & 0 deletions stix2validator/test/v20/intrusion_set_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,27 @@ def test_wellformed_intrusion_set(self):
results = validate_string(VALID_INTRUSION_SET, self.options)
self.assertTrue(results.is_valid)

def test_invalid_timestamp(self):
intrusion_set = copy.deepcopy(self.valid_intrusion_set)
intrusion_set['created'] = "2016-11-31T01:00:00.000Z"
self.assertFalseWithOptions(intrusion_set)

intrusion_set['created'] = "2016-04-06T20:03:48.123Z"
self.assertFalseWithOptions(intrusion_set)

intrusion_set['modified'] = "2016-04-06T20:03:48.123Z"
self.assertTrueWithOptions(intrusion_set)

intrusion_set['first_seen'] = "2016-04-06T20:03:48.123Z"
intrusion_set['last_seen'] = "2016-11-31T01:00:00.000Z"
self.assertFalseWithOptions(intrusion_set)

intrusion_set['last_seen'] = "2016-04-06T20:03:48.000Z"
self.assertFalseWithOptions(intrusion_set)

intrusion_set['last_seen'] = "2016-04-06T20:03:48.123Z"
self.assertTrueWithOptions(intrusion_set)

def test_country(self):
intrusion_set = copy.deepcopy(self.valid_intrusion_set)
intrusion_set['country'] = "USA"
Expand Down
11 changes: 11 additions & 0 deletions stix2validator/test/v20/malware_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@ def test_wellformed_malware(self):
results = validate_string(VALID_MALWARE, self.options)
self.assertTrue(results.is_valid)

def test_invalid_timestamp(self):
malware = copy.deepcopy(self.valid_malware)
malware['created'] = "2016-11-31T01:00:00.000Z"
self.assertFalseWithOptions(malware)

malware['created'] = "2016-05-12T08:17:27.123Z"
self.assertFalseWithOptions(malware)

malware['modified'] = "2016-05-12T08:17:27.123Z"
self.assertTrueWithOptions(malware)

def test_vocab_malware_label(self):
malware = copy.deepcopy(self.valid_malware)
malware['labels'] += "something"
Expand Down
20 changes: 20 additions & 0 deletions stix2validator/test/v20/observed_data_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -827,6 +827,26 @@ def test_invalid_observable_embedded_timestamp(self):
}
self.assertFalseWithOptions(observed_data)

def test_invalid_timestamp(self):
observed_data = copy.deepcopy(self.valid_observed_data)
observed_data['created'] = "2016-11-31T08:17:27.000Z"
self.assertFalseWithOptions(observed_data)

observed_data['created'] = "2016-04-06T19:58:16.123Z"
self.assertFalseWithOptions(observed_data)

observed_data['modified'] = "2016-04-06T19:58:16.123Z"
self.assertTrueWithOptions(observed_data)

observed_data['first_observed'] = "2016-11-31T08:17:27.000Z"
self.assertFalseWithOptions(observed_data)

observed_data['first_observed'] = "2015-12-21T19:00:00.123Z"
self.assertFalseWithOptions(observed_data)

observed_data['last_observed'] = "2015-12-21T19:00:00.123Z"
self.assertTrueWithOptions(observed_data)

def test_additional_schemas_custom_observable(self):
observed_data = copy.deepcopy(self.valid_observed_data)
observed_data['objects']['2'] = {
Expand Down
11 changes: 11 additions & 0 deletions stix2validator/test/v20/relationship_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ def test_wellformed_relationship(self):
results = validate_string(VALID_RELATIONSHIP, self.options)
self.assertTrue(results.is_valid)

def test_invalid_timestamp(self):
relationship = copy.deepcopy(self.valid_relationship)
relationship['created'] = "2016-11-31T01:00:00.000Z"
self.assertFalseWithOptions(relationship)

relationship['created'] = "2016-04-06T20:06:37.123Z"
self.assertFalseWithOptions(relationship)

relationship['modified'] = "2016-04-06T20:06:37.123Z"
self.assertTrueWithOptions(relationship)

def test_relationship_type(self):
relationship = copy.deepcopy(self.valid_relationship)
relationship['relationship_type'] = "SOMETHING"
Expand Down
14 changes: 13 additions & 1 deletion stix2validator/test/v20/report_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,17 @@ def test_vocab_report_label(self):

def test_invalid_timestamp(self):
report = copy.deepcopy(self.valid_report)
report['published'] = "2016-11-31T08:17:27.000000Z"
report['published'] = "2016-11-31T08:17:27.000Z"
self.assertFalseWithOptions(report)

report['published'] = "2016-05-21T19:59:11.000Z"
self.assertTrueWithOptions(report)

report['created'] = "2016-11-31T08:17:27.000Z"
self.assertFalseWithOptions(report)

report['created'] = "2016-05-21T19:59:11.123Z"
self.assertFalseWithOptions(report)

report['modified'] = "2016-05-21T19:59:11.123Z"
self.assertTrueWithOptions(report)
17 changes: 17 additions & 0 deletions stix2validator/test/v20/sighting_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,23 @@ def test_wellformed_report(self):
results = validate_string(VALID_SIGHTING, self.options)
self.assertTrue(results.is_valid)

def test_invalid_timestamp(self):
sighting = copy.deepcopy(self.valid_sighting)
sighting['created'] = "2016-11-31T01:00:00.000Z"
self.assertFalseWithOptions(sighting)

sighting['created'] = "2016-08-22T14:09:00.124Z"
self.assertFalseWithOptions(sighting)

sighting['modified'] = "2016-08-22T14:09:00.124Z"
self.assertTrueWithOptions(sighting)

sighting['last_seen'] = "2016-08-22T14:09:00.000Z"
self.assertFalseWithOptions(sighting)

sighting['last_seen'] = "2016-08-22T14:09:00.124Z"
self.assertTrueWithOptions(sighting)

def test_sighting_of_ref(self):
sighting = copy.deepcopy(self.valid_sighting)
sighting['sighting_of_ref'] = "bundle--36ffb872-1dd9-446e-b6f5-d58527e5b5d2"
Expand Down
11 changes: 11 additions & 0 deletions stix2validator/test/v20/threat_actor_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ def test_wellformed_threat_actor(self):
results = validate_string(VALID_THREAT_ACTOR, self.options)
self.assertTrue(results.is_valid)

def test_invalid_timestamp(self):
threat_actor = copy.deepcopy(self.valid_threat_actor)
threat_actor['created'] = "2016-11-31T01:00:00.000Z"
self.assertFalseWithOptions(threat_actor)

threat_actor['created'] = "2016-04-06T20:03:48.123Z"
self.assertFalseWithOptions(threat_actor)

threat_actor['modified'] = "2016-04-06T20:03:48.123Z"
self.assertTrueWithOptions(threat_actor)

def test_vocab_attack_motivation(self):
threat_actor = copy.deepcopy(self.valid_threat_actor)
threat_actor['primary_motivation'] = "selfishness"
Expand Down
11 changes: 11 additions & 0 deletions stix2validator/test/v20/tool_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,17 @@ def test_wellformed_tool(self):
results = validate_string(VALID_TOOL, self.options)
self.assertTrue(results.is_valid)

def test_invalid_timestamp(self):
tool = copy.deepcopy(self.valid_tool)
tool['created'] = "2016-11-31T01:00:00.000Z"
self.assertFalseWithOptions(tool)

tool['created'] = "2016-04-06T20:03:48.123Z"
self.assertFalseWithOptions(tool)

tool['modified'] = "2016-04-06T20:03:48.123Z"
self.assertTrueWithOptions(tool)

def test_vocab_tool_label(self):
tool = copy.deepcopy(self.valid_tool)
tool['labels'] += ["multi-purpose"]
Expand Down
11 changes: 11 additions & 0 deletions stix2validator/test/v20/vulnerability_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,17 @@ def test_incorrect_cve_source_name(self):
results = validate_parsed_json(vulnerability, self.options)
self.assertEqual(results.is_valid, False)

def test_invalid_timestamp(self):
vulnerability = copy.deepcopy(self.valid_vulnerability)
vulnerability['created'] = "2016-11-31T01:00:00.000Z"
self.assertFalseWithOptions(vulnerability)

vulnerability['created'] = "2016-05-12T08:17:27.123Z"
self.assertFalseWithOptions(vulnerability)

vulnerability['modified'] = "2016-05-12T08:17:27.123Z"
self.assertTrueWithOptions(vulnerability)

def test_url_no_hash(self):
vulnerability = copy.deepcopy(self.valid_vulnerability)
ext_refs = vulnerability['external_references']
Expand Down
5 changes: 4 additions & 1 deletion stix2validator/test/v21/attack_pattern_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,5 +140,8 @@ def test_invalid_timestamp(self):
attack_pattern['modified'] = "2017-02-29T08:17:27.000Z"
self.assertFalseWithOptions(attack_pattern)

attack_pattern['modified'] = "2016-02-29T08:17:27.000Z"
attack_pattern['created'] = "2016-02-29T08:17:27.000036Z"
self.assertFalseWithOptions(attack_pattern)

attack_pattern['modified'] = "2016-02-29T08:17:27.001Z"
self.assertTrueWithOptions(attack_pattern)
Loading

0 comments on commit 963af14

Please sign in to comment.