101

I see a lot of sites use GUIDs for password resets, unsubscribe requests and other forms of unique identification.

Presumably they are appealing because they are easy to generate, unique, non-sequential and seem random.

But are they safe enough for these purposes?

It seems to me that given a GUID, predicting subsequent GUIDs may be possible since (as far as I know) they're not intended to be cryptographically secure...or are they?

Note:

  • I'm not talking about sites that use a random blob of gobbledygook encoded in base64.
  • I'm talking about sites like this that appear to be using a raw guid:
    http://example.com/forgotPassword/?id=b4684ce3-ca5b-477f-8f4d-e05884a83d3c
AviD
  • 72,708
  • 22
  • 137
  • 218
Michael Haren
  • 1,112
  • 2
  • 7
  • 7
  • That depends if you can create/predict what's gonna be the next GUID in use. – Marcin Nov 30 '10 at 15:59
  • 2
    It all depends on exactly what you mean by GUID and how it was generated. Looking at a URL it may seem that it is in UUID format, and you may guess it was generated by Microsoft's insecure GUID algorithm, and thus it would not be suitable for any use like what you propose. But it might have been generated using a good cryptographically secure pseudo-random source like /dev/random in Linux, in which case it would be just fine. – nealmcb Nov 30 '10 at 20:59
  • @nealmcb: sure--this isn't a direct criticism of any particular site. Instead, I'm trying to confirm my suspicion that such a practice (secure ID via guid) is probably not good. Consensus seems to be that GUIDs are predictable (though non-trivial to predict), and more secure means should be used. – Michael Haren Nov 30 '10 at 21:35
  • 2
    @nealmcb, it isnt just MS' implementation, its the standard for GUIDs. – AviD Dec 01 '10 at 21:08
  • 1
    @avid We agree that nothing in the RFC specifies that even type 4 "random" UUIDS are cryptographically secure. My only point was that you could use a good implementation of the RFC for security purposes. E.g. on a modern Linux box with /dev/random, the libuuid library (and uuidgen program) will by default generate very good, unpredictable UUIDs. http://www.kernel.org/doc/man-pages/online/pages/man4/random.4.html But it is surely better for security software to directly use an API that is designed specifically to provide crypto randomness, since someone may carelessly port the code. – nealmcb Dec 02 '10 at 03:10
  • Depends how they're generated. Many people generate them securely, see also https://news.ycombinator.com/item?id=10631806 – rogerdpack Mar 06 '20 at 01:29
  • UUID is not the right tool for security capabilities. It's kind of like asking if a metal pipe can be used as a hammer. Better to simply use the correct tool. – jchook Oct 16 '21 at 20:30

6 Answers6

67

The UUID specification details several "versions" which are methods for generating the UUID. Most are aimed at ensuring uniqueness (that's the main point of UUID) by using, e.g., the current date. This is efficient but means that while the generated UUID are unique, they are also predictable, which makes them inadequate for some security usages.

The "version 4" UUID generation method (in section 4.4), however, is supposed to use a cryptographically strong random number generator. 6 of the 128 bits are fixed to a conventional value (to indicate that this is a version 4 UUID, namely), so this leaves 122 bits from the RNG.

If the underlying RNG is secure (e.g. /dev/urandom on a Linux/MacOS/*BSD system, or CryptGenRandom() on Windows) then given many generated UUID, an attacker is not supposed to be able to predict the next one with success probability higher than 2-122, which is adequately small for most purposes, including launch codes for nuclear missiles.

122 random bits ensure uniqueness with high probability. If you generate many version 4 UUID and accumulate them, you may expect to encounter your first collision after about 261 UUID -- that's about 2 billions of billions; simply storing that number of UUID would use more than 30 millions of terabytes. If you consider "only" 1012 such UUID (one thousand of billions, storable over 16 terabytes), then risks of having two identical UUID among these are about 9.4*10-14, i.e. about 700 thousands times less probable than winning millions of dollars at the lottery.

Therefore, UUID are appropriate for security purposes if (and only if) they are "version 4" UUID generated with a secure RNG.

Thomas Pornin
  • 322,884
  • 58
  • 787
  • 955
  • It says"The version 4 UUID is meant for generating UUIDs from truly-random or pseudo-random numbers." (FWIW) ... – rogerdpack Mar 06 '20 at 01:28
  • UUID generators can still produce predictable UUID sequences even when using CSPRNG. The spec does not require them to generate entirely new random bytes for each successive UUID. Also the spec explicitly says UUID **should not** be used for auth tokens. – jchook Oct 16 '21 at 20:22
47

Are they safe enough for the purposes you described? In my opinion, generally yes. Are they safe enough in applications where security is a significant concern? No. They're generated using a non-random algorithm, so they are not in any way cryptographically random or secure.

So for an unsubscribe or subscription verification function, I really don't see a security issue. To identify a user of an online banking application on the other hand, (or really probably even a password reset function of a site where identity is valuable) GUIDs are definitely inadequate.

For more information, you might want to check out section 6 (Security Considerations) of the RFC 4122 for GUIDs (or Universally Unique Identifiers).

Xander
  • 35,616
  • 27
  • 114
  • 141
  • 6
    The purpose he described is exactly a password reset function. While it is clear that you are stating that GUID is *not* acceptable for any security use, your first sentence contradicts that. – AviD Nov 30 '10 at 16:38
  • 2
    And I'd agree that it's acceptable for a password reset function on most sites. Not for banking sites, or sites where assuming another user's identity would be particularly valuable, but most sites simply don't present a valuable target for this sort of attack, or a high enough volume of password-reset requests for an attack of this nature to work in the first place. – Xander Nov 30 '10 at 16:49
  • 1
    Password reset at most organisations I have worked was definitely considered at a lower security level than authentication for transactional sites etc. Yes, it is a vector for attack, however the limitations imposed (time, knowledge of secret information etc) and the cost reductions made in simplifying password self reset (any reduction in helpdesk calls saves money) are generally considered enough of a driver. – Rory Alsop Nov 30 '10 at 18:26
  • 3
    Hmm, I guess that's true, for low-value sites GUID may be good enough. But really, as @massimo mentions in his answer, why bother? Cryptorandom numbers are not costly, neither in dev time or processing time. – AviD Nov 30 '10 at 19:56
  • 3
    Point taken. I'd agree that even if they're suitable for the purpose at hand, they're still not the best option from a security perspective. – Xander Nov 30 '10 at 21:45
6

They are secure on Windows 2000 or newer. Your vulnerability & risk depends on how the GUID is generated. Windows 2000 or newer uses version 4 of the GUID which is cryptographically secure.

For more information see this MSDN link and this stack overflow question. (Thanks to Jordan Rieger in the comments)

makerofthings7
  • 50,488
  • 54
  • 253
  • 542
  • 4
    Why complicate things by encrypting a not-so-random number? Better and simpler to just generate a truly unpredictable random number. That is easy with /dev/random or /dev/urandom on Linux. We just need a simple specific recipe here for other platforms. – nealmcb Jan 30 '11 at 16:27
  • @nealmcb sometimes it's not possible to define the randomness of this number (e.g. the ID comes from a backend system from 3rd party). May not apply the OP – makerofthings7 Feb 17 '17 at 18:45
  • 1
    According to https://msdn.microsoft.com/en-us/library/bb417a2c-7a58-404f-84dd-6b494ecf0d13#id11, since Windows 2000 back in 1999, "the random bits for all version 4 GUIDs built in Windows are obtained via the Windows CryptGenRandom cryptographic API or the equivalent, the same source that is used for generation of cryptographic keys". So I'd say you could call them cryptographically secure -- at least to the extent of the 122 bits of entropy they provide. – Jordan Rieger May 28 '18 at 19:45
  • @JordanRieger Thanks - updated. I tried to find the containing document "home", but was hindered by MSDN navigation. Is this product documentation for ".NET" "Windows", or something else? – makerofthings7 May 28 '18 at 21:25
  • 1
    @CHICoder007 MSDN navigation seems broken. Following the section numbers backward as far as possible leads to https://msdn.microsoft.com/en-us/library/cc246025.aspx?f=255&MSPPError=-2147217396, a dead end. It's definitely Windows SDK documentation of some kind. I found it by stumbling on this blog post: http://joakim.uddholm.com/posts/predicting-net-guidnewguid.html (the doc page may have been updated since then as the blog references end note 9 when it's actually end note 11.) This also matches a recent debug/step-through by Will Dean in https://stackoverflow.com/a/35384818/284704. – Jordan Rieger May 29 '18 at 00:26
3

If you're using a common development language creating a one shot generator of unique random numbers using a proper crypto function is not so difficult (we're talking about 10 lines of code that are available as samples in the most common languages simply using Google) and so using a simple new guid it's basically laziness from developer point of view.

In the scenario described they are "secure enough", if the Guid passed in the forgot password function has some basic features:

1) It's really a one shot value that has no relationship with the user id, so, once the password has been reset, cannot be used anymore

2) It has a defined window of time for its validity (you can reset password in the next 30 minutes or something like that)

If using the same Guid you can reset the password more than once or guess the guid and reset password of users that did not ask for a password reset or, like Avid describe in the comment, try to get access to reset password using some kind of replay attach then it's the application design that's faulty and using or not using a Guid is not the real problem.

So if you're not dealing with very sensitive information then maybe a guid could work, but why do not make things in a proper way the first time and use a proper crypto api to generate a secure random string?

Regards Massimo

  • I agree with the first part of your answer generating crypto-random numbers is extremely easy (and should take substantially *less* than 10 LoC...). However, in the scenario described they are **not** secure enough, since there is no guarantee that the password is reset immediately: There is usually a non-trivial window of validity. – AviD Nov 30 '10 at 16:40
  • 3
    For example, consider the following: often this scheme is used to send a link to the user's preregistered email, which will allow direct access to reset the user's password. As an attacker, I would generate enough of these links/GUIDs till I could semi-reliably calculate the next batch, then ask to send the link to my victim (essentially having the user ask for a password reset). Then I would not care about access to the user's email, since I could just guess the GUID/link. – AviD Nov 30 '10 at 16:44
  • 2
    @Rory, I was talking about the inherent guessability of GUIDs (given enough prior data), not replay attacks... – AviD Nov 30 '10 at 19:55
1

According to Raymond Chen at Microsoft, even version 4 GUIDs used in Windows since 2000 are not cryptographically secure. They use the basic random number generator, which can allow someone to predict past and future GUIDs if they know the state of the generator. Granted, this would only be relevant to a security-sensitive application. It's important to know that standard Guid.NewGuid() values are only guaranteed to be "most certainly" unique, not secure.

0

Fake "GUID"s, which are not generated by any GUID generation algorithm, but which instead are simply 128 bits (16 bytes) generated by a cryptographically secure PRNG, and which are merely represented using conventional GUID hex-with-hyphens encoding, are mostly safe for one-time tokens.

You do run into the birthday problem, however, since the existence of a collision is around 2^-64 for 128-bit tokens.

Better to use 256-bit or 512-bit tokens, where the existence of a collision is around 2^-128 or 2^-256.

yfeldblum
  • 2,817
  • 21
  • 13