GH-188: Restrict valid UUID values.

stix2.0
Greg Back 2018-06-21 12:42:10 -05:00
parent 399a3a594e
commit b2c6acfbf6
2 changed files with 54 additions and 9 deletions

View File

@ -172,10 +172,13 @@ class IDProperty(Property):
if not value.startswith(self.required_prefix): if not value.startswith(self.required_prefix):
raise ValueError("must start with '{0}'.".format(self.required_prefix)) raise ValueError("must start with '{0}'.".format(self.required_prefix))
try: try:
uuid.UUID(value.split('--', 1)[1]) type, orig_id = value.split('--', maxsplit=1)
except Exception: new_uuid = uuid.UUID(orig_id)
if new_uuid.variant != uuid.RFC_4122 or new_uuid.version != 4:
raise ValueError()
except ValueError:
raise ValueError("must have a valid UUID after the prefix.") raise ValueError("must have a valid UUID after the prefix.")
return value return "--".join([type, str(new_uuid)])
def default(self): def default(self):
return self.required_prefix + str(uuid.uuid4()) return self.required_prefix + str(uuid.uuid4())

View File

@ -1,3 +1,5 @@
import uuid
import pytest import pytest
from stix2 import CustomObject, EmailMIMEComponent, ExtensionsProperty, TCPExt from stix2 import CustomObject, EmailMIMEComponent, ExtensionsProperty, TCPExt
@ -85,18 +87,58 @@ def test_type_property():
assert prop.clean(prop.default()) assert prop.clean(prop.default())
def test_id_property(): ID_PROP = IDProperty('my-type')
idprop = IDProperty('my-type') MY_ID = 'my-type--232c9d3f-49fc-4440-bb01-607f638778e7'
assert idprop.clean('my-type--90aaca8a-1110-5d32-956d-ac2f34a1bd8c')
@pytest.mark.parametrize("value", [
MY_ID,
'my-type--00000000-0000-4000-8000-000000000000',
])
def test_id_property_valid(value):
assert ID_PROP.clean(value) == value
@pytest.mark.parametrize("value", [
# These are all acceptable input formats that will get translated to the
# same ID shown above
MY_ID,
# These formats are all used in the uuid.UUID() documentation as valid ways
# to initialize a UUID. We are ok with accepting them, as they will
# get coerced to the right format for an ID.
'my-type--{232c9d3f-49fc-4440-bb01-607f638778e7}',
'my-type--232c9d3f49fc4440bb01607f638778e7',
'my-type--urn:uuid:232c9d3f-49fc-4440-bb01-607f638778e7',
# The extra "--" are ignored by split() and accepted by uuid.UUID()
'my-type--232c9d3f--49fc--4440--bb01--607f638778e7',
])
def test_id_property_transform(value):
assert ID_PROP.clean(value) == MY_ID
def test_id_property_wrong_type():
with pytest.raises(ValueError) as excinfo: with pytest.raises(ValueError) as excinfo:
idprop.clean('not-my-type--90aaca8a-1110-5d32-956d-ac2f34a1bd8c') ID_PROP.clean('not-my-type--232c9d3f-49fc-4440-bb01-607f638778e7')
assert str(excinfo.value) == "must start with 'my-type--'." assert str(excinfo.value) == "must start with 'my-type--'."
@pytest.mark.parametrize("value", [
'my-type--foo',
# Not a v4 UUID
'my-type--00000000-0000-0000-0000-000000000000',
'my-type--' + str(uuid.uuid1()),
'my-type--' + str(uuid.uuid3(uuid.NAMESPACE_DNS, "example.org")),
'my-type--' + str(uuid.uuid5(uuid.NAMESPACE_DNS, "example.org")),
])
def test_id_property_not_a_valid_hex_uuid(value):
with pytest.raises(ValueError) as excinfo: with pytest.raises(ValueError) as excinfo:
idprop.clean('my-type--foo') ID_PROP.clean(value)
assert str(excinfo.value) == "must have a valid UUID after the prefix." assert str(excinfo.value) == "must have a valid UUID after the prefix."
assert idprop.clean(idprop.default())
def test_id_property_default():
default = ID_PROP.default()
assert ID_PROP.clean(default) == default
@pytest.mark.parametrize("value", [ @pytest.mark.parametrize("value", [