Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed timestamp fields comparison #198

Merged
merged 12 commits into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading