UUID() returns a value that conforms to UUID version 1 as described in RFC 4122. The value is a 128-bit number represented as a utf8 string of five hexadecimal numbers in aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee format:
The first three numbers are generated from the low, middle, and high parts of a timestamp. The high part also includes the UUID version number.
The fourth number preserves temporal uniqueness in case the timestamp value loses monotonicity (for example, due to daylight saving time).
The fifth number is an IEEE 802 node number that provides spatial uniqueness. A random number is substituted if the latter is not available (for example, because the host device has no Ethernet card, or it is unknown how to find the hardware address of an interface on the host operating system). In this case, spatial uniqueness cannot be guaranteed. Nevertheless, a collision should have very low probability.
The MAC address of an interface is taken into account only on FreeBSD and Linux. On other operating systems, MySQL uses a randomly generated 48-bit number.
I don't know if MySQL has built-in UUIDv4 though. pg does.
We really ought to use names for them, not version numbers. If someone wrote "Timestamp-based UUIDs Are Not Fully Random", well, by the time you've typed out the title of your blog post you'd have figured out what the problem was.
It was relatively painless, sure, but I seem to remember having to add it.
/dev/urandom does not produce such non-random results; the comparison is rather far-fetched. /dev/urandom is suitable for virtually all tasks, including cryptography[1]. It's the same as /dev/random on various BSDs, even.
No, the lesson here is to not assume a "random" function is cryptographically secure unless stated otherwise. The same article could be made about Math.random or rand.
Or if you have an application installed on personal machines, it's leaking identifying information about those machines.
Since when someone on earth has recommended something like that?
UUIDs are time/mac address sensitive. They have version info within. They make an awful, guessable secret. It's just that: An unique identifier across the globe and not just your database.
https://en.wikipedia.org/wiki/Universally_unique_identifier#...
Why would you ever assume that? UUIDs could be formed from a low-entropy LCGRNG and still match the specifications.
Any secret should be generated with cryptographically secure random number generators. Calling "UUID" instead of like, BCrypt or something would be a major red flag to me. Heck, a modern cryptographically secure secret can be generated from Intel's "RDSEED" assembly instruction, which provides a hardware-random source of entropy, as well as entropy guarantees. (You'll probably use this assembly instruction if you are using /dev/urandom)
As always, it's the programmer's duty to investigate the RNG before relying on the entropy of some function's result.
UUIDs based on a CSPRNG and used as a password/token have some nice features--they're of fixed length, easy to validate for well-formedness, easy to serialize or deserialize in a variety of conventions.
In our case it wasn't a problem, but I couldn't help thinking that this was a nice information leak where you could find out some property of a dataset that was never intended to be retained. Just imagine that you mobile sign-ups had one kind of UUID and your web sign-ups the other kind. Though you might not explicitly store the information how someone signed up you inadvertently really do.
And now if you are tempted to ask why we stored our UUIDs as strings - just don't...
UUID VARIANT TYPE TIME
4f95de28-0fd1-48db-ad2e-34ecd169c483 DCE random
4331cb9e-1d91-11e9-be2c-45923c63e8a2 DCE time-based 2019-01-21 17:28:54,631107+02:00
4331cc4c-1d91-11e9-be2c-45923c63e8a2 DCE time-based 2019-01-21 17:28:54,631124+02:00
c7e2f124-f6ba-4434-843f-89958a7436ec DCE random
3e18f8dd-b1d3-4e16-8a81-4bdceac91772 DCE random
Explanation of the output: Variants
DCE The Open Software Foundation's (OSF) Distributed Computing Environment UUIDs.
Types
time-based The DCE time based.
random RFC 4122 random.I've never used UUIDs for secrets, but I've often dependended on UUIDs to be uniform - as the primary identifier when passing data around inside distributed systems. If the chance of collision is implementation dependent, that could end really badly.
TIL only version 4 is generated using a random source.
Thing for example getDocById.php?id=...
Of course it does not have to be UUID, but this can have some benefits as you DB for example may have a nice datatype for it.
* One that is better served with a UUID than a random binary blob.
For example, a company I used to work for named IntegriShield is essentially a for-hire private Internet police company. When I got there, we would take an automatic screenshot of a web site and then send it to the people who were doing something "bad" (for whatever the definition of "bad" was) and you would essentially visit some sort of link like
https://api.integrishield.com/(api route)/12345.png
Of course if these folks were to increment the identifier they would see other screenshots we were capturing -- though at the time that was not very helpful as we would routinely capture every web site that we crawled, so most of them didn't have anything interesting on them.One of my jobs there was to improve this process: reduce image storage costs and increase the productivity of the humans who had to look at these web sites to determine what had gone wrong. With my contribution, we could intelligently flag language that might be "bad" and then capture enough metadata that we could later reconstruct screenshots which highlighted those "bad" things, after a human being had looked at them and said "no, these things are okay but those things really are bad" and deleted half of our highlights. So the screenshots were now only generated after we were done and clearly highlighted what was wrong, and then it becomes a serious problem if folks from one of these companies can see what their peers are doing.
We did not switch to UUIDs but rather just encrypted the counter with a server key, but the point is still that you would now visit
https://api.integrishield.com/(other-api-route)/2121a46a4c24c512965671f8fb269f0b.png
and that would give you access to this image, but now if you just change that to a random identifier there is only a 2^-64 chance that you would successfully alight upon a valid image, and if you don't we can increment a counter in the database and if that gets too large too fast we can send out emails saying "warning, lots of 404s are happening".UUIDs v4 (chosen securely randomly) have the same properties from the very start. You can easily use them in cases where the security model demands that some non-client must be able to access some sort of information simply by knowing the identifier.
We could have chosen something more complicated, of course, like creating a many-to-many table relating screenshots to email addresses and then embedding the email address somehow in the URL,
https://api.integrishield.com/(more-api)/12345.png?email=someone%40example.com
https://api.integrishield.com/(more-api)/12345.png?emailBatch=67890
Of those the first is worrisome -- there's no reason that one company couldn't have access to another company's email addresses for their legal compliance department and indeed in many cases they should. And if we try to obfuscate that with an auto-incrementing ID like in the second case then we're actually legit broken: remember, I told you that the screenshots are generated shortly before the emails get sent out, so they both would tend to increment in lockstep, you might have to try only 5-10 screenshot/batch pairs before alighting upon one you weren't meant to see. So the batch needs to be protected by, what, UUIDv4? And you have the same problem that you had before.In other words, you shouldn't use a non-cryptographic RNG for security purposes.
There are different types of UUIDs [1]. MySQL generates version 1 UUIDs - you can tell by the first digit of the third block. It looks like something else is also generating UUIDs, using the v4 format - so you have two different types of UUID in your database:
4331cb9e-1d91-11e9-be2c-45923c63e8a2 # v1
c7e2f124-f6ba-4434-843f-89958a7436ec # v4
v1 UUIDs are typically based on the MAC address of your computer and the current time. Online tools exist [2] that decode the uuid and tell you it was created at 2019-01-21 10:28:55 (UTC)
v4 UUIDs are random.
[1] https://en.wikipedia.org/wiki/Universally_unique_identifier
V4 UUIDs are supposed to be random.
"Do not assume that UUIDs are hard to guess; they should not be used as security capabilities (identifiers whose mere possession grants access), for example."
There are a million things that get posted on Hacker News that are "beginner level". How many tutorials have we gotten about Rust on here? I don't think that's a bad thing.
They are certainly useful for creating unique id's, but for randomness? No.