Phobos randomUUID is not suitable to generate secrets
cpicard at purrfect.fr
Mon Aug 31 07:40:45 UTC 2020
As always when I make an appearance it's that something has gone
wrong. Either in a popular library or D itself... This time it's
a little bit of both.
There are many projects out there that use UUIDs to generate
secrets such as session tokens and password recovery tokens.
Other projects use it to protect against things like symlink
attacks by generating temporary file names, or reduce the risk of
IDOR by generating user IDs etc.
The issue is, they shouldn't use Phobos' randomUUID() for that.
The Phobos implementation of UUID4 doesn't use cryptographic
randomness which leads to predictable UUIDs, putting all these
projects at risk.
Now, the question is: who's at fault? Is it Phobos? The RFC
doesn't enforce the use of cryptographic randomness and the
library doesn't claim that these UUIDs are suitable for secret
generation. Is it the developers then? Every other language that
I can think of uses cryptographic randomness for UUID4 because
this kind of use is very common, so I think it is normal for
developers to expect it to work similarly in D.
I personally think that Phobos must be changed. We can nag
projects all day long, but any new developer will come and fall
into the same trap. Furthermore I have thought for a long time
that Phobos needs to provide a standard interface to the system's
CSPRNG (CryptGenRandom on Windows, getrandom() or /dev/urandom on
Linux, /dev/random on Unix). This is a component that does not
involve the difficulty of cryptographic code (since you're not
recoding anything) and is absolutely critical to so many
operations that are very common at the age of secure
communications. People use the path of least resistance and at
the moment it is incredibly harder to use secure randomness
compared to reaching for std.random.uniform(). Clearly randomUUID
itself fell into this case.
Then again some might argue that developers should read the RFC
of anything they use and, well, as much as I disagree, the RFC is
the RFC, wrong as it may be.
I obviously can't solve that conundrum on my own and there are
far too many projects impacted for me to take the time and reach
them all, so I've written an article showing how to predict
Phobos UUIDs in practice. I hope this shows that this is a very
practical and important issue that must be dealt with, and the
best way for that would be to generate cryptographically secure
UUIDs in Phobos.
tl;dr: At the moment predicting a future UUID takes only a few
thousand requests. It's nothing when it comes to things like
trying session cookies or password recovery tokens. If you are a
project manager, check whether you use randomUUID to generate
secrets and replace it by cryptographically secure UUID.
Even if you don't care about the details of the attack, there's a
section at the end of the article that details how to fix the
issue and (maybe more importantly) how *not* to fix the issue.
Enjoy your day!
More information about the Digitalmars-d