8

I am generating "hard to guess" URL by:

import uuid
url = uuid.uuid4()

URL is stored in Postgres database in field with ordinary index (for quick searching). Datatype of field is uuid: https://www.postgresql.org/docs/9.1/datatype-uuid.html

Another possibility for creating "hard to guess" URL is use secrets module and store it in some Postgres string datatype:

import secrets
url = secrets.token_urlsafe()

What is better for quick searching in database and for safety of random generated url?

Thanks

user13978
  • 113
  • 1
  • 5

1 Answers1

1

Unlike secrets.token_urlsafe, there is no guarantee about the quality of uuid4. secrets.token_urlsafe is meant for generating a shared secret. uuid4 is meant for generating a likely universally unique identifier.

The thing is you should probably use them both: a secret token and an identifier that you look up in the database:

create table foo (
    id uuid primary key,
    token text not null
);

Notice that the length of the token_urlsafe is supposed to change over time, so that future Python versions are likely to generate a longer string.

  • 2
    Thanks... But here is some introdution: Version 4 UUIDs are essentially just 16 bytes of randomness pulled from a cryptographically secure random number generator, with some bit-twiddling to identify the UUID version and variant (https://stackoverflow.com/questions/703035/when-are-you-truly-forced-to-use-uuid-as-part-of-the-design/786541#786541). Is UUID4 really insecure for hard to guess URL and why? Thanks – user13978 May 04 '19 at 20:31
  • @user13978 The "pulled from a CS RNG" part might not be true. This answer has some great points about really knowing the security guarantees and trusting them not changing when changing e.g. the python runtime: https://stackoverflow.com/a/53542384 (TLDR: neither python docs, nor UUID specification guarantee a high quality randomness source for UUIDv4 in itself) – xuiqzy May 09 '22 at 23:52
  • @user13978 The cryptographic security not being specified in the UUID specification likely comes down to UUIDs main goal being globally or unique in your application most of the time, not necessarily unpredictable/unguessable by an adversary, like you want a password reset link to be for example. The above referenced answer and the specification itself touch on that point of not needing true randomness necessarily. – xuiqzy May 09 '22 at 23:55