(core) Use standard library uuid.uuidv4 when possible for better randomness

Summary: Using the `random` module in the Grist `UUID()` function is not cryptographically secure, and is only necessary for the old pynbox (Python 2) sandbox which doesn't support `os.urandom`. This diff uses the `uuid.uuidv4()` function from the Python standard library when possible, which is more secure, only falling back to the old implementation when necessary.

Test Plan: Added Python unit tests to check both implementations.

Reviewers: dsagal

Subscribers: paulfitz, dsagal

Differential Revision: https://phab.getgrist.com/D3578
This commit is contained in:
Alex Hall
2022-08-11 22:32:34 +02:00
parent 3ad78590c2
commit 31f54065f5
2 changed files with 50 additions and 4 deletions

View File

@@ -872,7 +872,14 @@ def UUID():
This would only calculate UUID() once and freeze the calculated value. By contrast, a regular formula
may get recalculated any time the document is reloaded, producing a different value for UUID() each time.
"""
if six.PY2:
return str(uuid.UUID(bytes=[chr(random.randrange(0, 256)) for _ in xrange(0, 16)], version=4))
else:
return str(uuid.UUID(bytes=bytes([random.randrange(0, 256) for _ in range(0, 16)]), version=4))
try:
uid = uuid.uuid4()
except Exception:
# Pynbox doesn't support the above because it doesn't support `os.urandom()`.
# Using the `random` module is less secure but should be OK.
if six.PY2:
byts = [chr(random.randrange(0, 256)) for _ in xrange(0, 16)]
else:
byts = bytes([random.randrange(0, 256) for _ in range(0, 16)])
uid = uuid.UUID(bytes=byts, version=4)
return str(uid)