-
Notifications
You must be signed in to change notification settings - Fork 23
Description
Here is an example with stix2-patterns==1.3.2
:
$ validate-patterns
Enter a pattern to validate: [file:hashes.MD5 = '3858f62230ac3c915f300c664312c63f']
PASS: [file:hashes.MD5 = '3858f62230ac3c915f300c664312c63f']
Enter a pattern to validate: [file:hashes.MD5 = '3858f62230ac3c915f300c664312c63']
FAIL: '3858f62230ac3c915f300c664312c63' is not a valid MD5 hash
Enter a pattern to validate: [email-addr:value = 'MUST NOT <[email protected]>']
PASS: [email-addr:value = 'MUST NOT <[email protected]>']
Enter a pattern to validate: [ipv4-addr:value = 'http://1.2.3.4/login']
PASS: [ipv4-addr:value = 'http://1.2.3.4/login']
Enter a pattern to validate:
PASSED: 3 patterns
FAILED: 1 patterns
For email-addr:value
the example above explicitly contradicts what the spec requires:
Specifies the value of the email address. This MUST NOT include the display name.
For ipv4-addr:value
the spec is softer, but an URL is obviously not a CIDR:
Specifies the values of one or more IPv4 addresses expressed using CIDR notation.
And so on for bunch of MUSTs and plain definitions of what is what in the spec about SCOs.
Invalid ipv4-addr
STIX 2.1 SCOs is already something that one can see in the wild.
Code-wise property-level validation happens here. I think the same regex-based approach can cover many if not most of the constraints (though that's understandingly quite a bit of work).
cti-pattern-validator/stix2patterns/v21/object_validator.py
Lines 24 to 42 in 52de2bc
def verify_object(patt_data): | |
error_list = [] | |
msg = "FAIL: '{}' is not a valid {} hash" | |
# iterate over observed objects | |
for type_name, comp in patt_data.comparisons.items(): | |
for obj_path, op, value in comp: | |
if 'hashes' in obj_path: | |
hash_selector = obj_path[-1] | |
if hash_selector is not stix2patterns.inspector.INDEX_STAR: | |
hash_type = \ | |
hash_selector.upper().replace('-', '').replace("'", "") | |
hash_string = value.replace("'", "") | |
if hash_type in HASHES_REGEX: | |
if not re.match(HASHES_REGEX[hash_type][0], hash_string): | |
error_list.append( | |
msg.format(hash_string, hash_selector) | |
) | |
return error_list |