Lion Cipher Lab
Take apart UUID versions 1, 4 and 7, and measure which ones leak or can be guessed
- Foundations
- Intermediate
- ~50 min
- Free · no account required
Why it matters
UUIDs are everywhere: order numbers, document links, session records, API paths. Developers often pick one version without knowing what is inside it, and then make a security argument about it: 'nobody can guess that'. Sometimes that is true and sometimes it is badly wrong. A version 1 UUID carries the exact time it was made and, on many machines, the computer's network card address. A version 7 carries the time to the millisecond. A version 4 carries 122 random bits, if the program used a proper random source. This lab makes you take each one apart by hand, so you can read any UUID you meet…
What you'll learn
- decoding a UUID by hand with shifts and masks: the 4-bit version nibble, the variant bits (10x), and every field of v1, v4 and v7 per RFC 9562
- recovering a uuid1's creation time to 100 ns and its node, and reading the multicast bit to tell a real MAC (bit 0, as on the test machine) from a random node Python made up
- recovering a uuid7's creation time to the millisecond from its first 48 bits
- measuring a generator instead of trusting it: on Python 3.12/Windows the clock ticks every 15.6 ms and about 98% of back-to-back uuid1 timestamps differ by exactly 1 (98.9% and 98.1% in two runs)
- turning that into a search space: a v1 neighbour within one second hid in 21.0 bits on 3.12 and 38.3 bits on 3.14; a 3.14 uuid7 in the same ms kept 32 random bits; v4 keeps 122
- showing v7's time leak on synthetic data: a 25% sample of order ids rebuilt the hourly activity curve (r = 0.894) and estimated 580 orders a day against a true 582
- measuring why teams accept that leak: 200,000 SQLite inserts keyed by v7 ran 2.9 to 4.55 times faster than by v4 across four runs
- stating the rule from RFC 9562 and OWASP API1:2023: a hard-to-guess id is not access control; every object needs an authorization check
Steps in this lab
- What a UUID is, and the question this lab answers
- Set up: Python, a folder, a terminal
- Take one of each apart by hand
- What your uuid1 just told everyone: when, and which machine
- Measure how much of a neighbour id is really unknown
- Why version 4 holds: where its 122 bits come from
- Honest negative 1: a v4-SHAPED id is only as good as its generator
- Honest negative 2: version 7 cannot be guessed, but it tells time
- Honest negative 3: why people choose v7 anyway (measured in SQLite)
- Hard to guess is not access control
- Do it better: a short decision checklist