[go: up one dir, main page]

Skip to content

Stop using `Math.random()` to generate the initialization vector when getting a fully random UUID

Problem

When generating random numbers, Math.random() should never be in that call stack.

In our initial implementation of a UUID tool, we needed a way to seed the initialization vector (IV) of the random number generator.
In those circumstances, the IV values were whatever input the consumer passed.

However, when the consumer passed no IV seed values, the utility falls back to generating a very large integer value that has Math.random at its heart.

Concern

Right now, there really isn't a problem with this.
As far as I know, no one using the UUID utility is doing so in a scenario where the poor randomness of Math.random would matter.

However, to be on the safe side, we should prevent potential collision attacks and switch the random number generator to use better random values.

Fix

We already generate "cryptographically secure" random values using the consumer IV seeds.

We should extract that process so that it can also be unseeded (e.g. crypto.getRandomValues( new Uint8Array( 16 ) ) for high control or simply deferring to the built-in RNG in uuid for low control). If we choose to defer to uuids RNG (which is roughly equivalent to that previous snippet), we can simply remove the random: option when there are no seeds.

Important Notes

In the case of seeded values, it's very important that the output matches whatever the output was before.

However, in the case of a fully random UUID, there should be no expectation that any one call will output the same value as any other call (in fact, they never should).

Switching the underlying source of randomness to be more random should thus have no impact on consumers in terms of unmet expectations that might be considered a "defect."