remote_server: Improve uuid validation at the server/register endpoint.

As explained in the comments in the code, just doing UUID(string) and
catching ValueError is not enough, because the uuid library sometimes
tries to modify the string to convert it into a valid UUID:

>>> a = '18cedb98-5222-5f34-50a9-fc418e1ba972'
>>> uuid.UUID(a, version=4)
UUID('18cedb98-5222-4f34-90a9-fc418e1ba972')
This commit is contained in:
Mateusz Mandera 2021-12-30 15:32:48 +01:00 committed by Tim Abbott
parent 9d85f64e5a
commit 4153b5c517
2 changed files with 15 additions and 1 deletions

View File

@ -2470,6 +2470,14 @@ class PushBouncerSignupTest(ZulipTestCase):
result = self.client_post("/api/v1/remotes/server/register", request)
self.assert_json_error(result, "Invalid UUID")
# This looks mostly like a proper UUID, but isn't actually a valid UUIDv4,
# which makes it slip past a basic validation via initializing uuid.UUID with it.
# Thus we should test this scenario separately.
zulip_org_id = "18cedb98-5222-5f34-50a9-fc418e1ba972"
request["zulip_org_id"] = zulip_org_id
result = self.client_post("/api/v1/remotes/server/register", request)
self.assert_json_error(result, "Invalid UUID")
def test_push_signup_success(self) -> None:
zulip_org_id = str(uuid.uuid4())
zulip_org_key = get_random_string(64)

View File

@ -53,7 +53,13 @@ def validate_entity(entity: Union[UserProfile, RemoteZulipServer]) -> RemoteZuli
def validate_uuid(uuid: str) -> None:
try:
UUID(uuid, version=4)
uuid_object = UUID(uuid, version=4)
# The UUID initialization under some circumstances will modify the uuid
# string to create a valid UUIDv4, instead of raising a ValueError.
# The submitted uuid needing to be modified means it's invalid, so
# we need to check for that condition.
if str(uuid_object) != uuid:
raise ValidationError(err_("Invalid UUID"))
except ValueError:
raise ValidationError(err_("Invalid UUID"))