Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cryptographically secure random UUIDs #511

Closed
bcoe opened this issue Apr 9, 2021 · 15 comments
Closed

Cryptographically secure random UUIDs #511

bcoe opened this issue Apr 9, 2021 · 15 comments

Comments

@bcoe
Copy link

bcoe commented Apr 9, 2021

Request for Mozilla Position on an Emerging Web Specification

  • Specification Title: UUID
  • Specification or proposal URL: https://wicg.github.io/uuid/
  • Caniuse.com URL (optional): N/A
  • Bugzilla URL (optional): N/A
  • Mozillians who can provide input (optional): N/A

Other information

Effort in TC39:

This specification was originally worked on in TC39, but it was determined that the need for a CSRNG made WICG a more appropriate venue, given that Web Cryptography is part of the web platform.

Refs: https://github.com/tc39/proposal-uuid

Repository for Feedback:

Feedback can also be provided in the issue tracker here.

@annevk
Copy link
Contributor

annevk commented Apr 12, 2021

I looked at web-platform-tests /common/utils.js and it indeed seems to use the somewhat broken Math.random() path. Probably not a problem in practice there, but it does seem good to expose a safe version of this by default.

I would suggest worth prototyping.

One question though, what's the path toward standardizing this? Web Crypto looks like abandonware or can it still be maintained somehow?

(I also filed some quibbles as issues directly.)

@bcoe
Copy link
Author

bcoe commented Apr 15, 2021

One question though, what's the path toward standardizing this? Web Crypto looks like abandonware or can it still be maintained somehow?

A couple thoughts come to mind:

  1. we could use the crypto namespace, but work on the feature within another working group (perhaps WHATWG); the only real dependency on Web Crypto being the requirement for a Cryptographically Secure Pseudo Random Number Generator.
  2. @domenic pointed out to me, when discussing this topic, that Web Crypto is getting some attention recently. Perhaps this would be a minimal enough addition to the spec, that it could be added during routine maintenance of the spec, vs., spinning up a working group.

Interested to hear your and @domenic's further thoughts.

@annevk
Copy link
Contributor

annevk commented Apr 15, 2021

Yeah, I suppose 1 is an option, but I'm personally not a big fan of spreading out the definition of an interface. For 2 you need an actual WG because of IPR. One option might be getting the WebAppSec WG to adopt it in its charter and scope it to maintenance and the addition of this method as to not ruffle too many feathers.

@hsivonen
Copy link
Member

Personally, I don't see this as particularly worthwhile as part of the platform compared to publishing a small CC0-licensed copypasteable function that calls crypto.getRandomValues() and formats a UUID string based on the result.

@bcoe
Copy link
Author

bcoe commented Apr 16, 2021

I don't see this as particularly worthwhile as part of the platform compared to publishing a small CC0-licensed copypasteable function that calls crypto.getRandomValues()

I understand that the implementation of a UUID isn't very many lines of code, but it is slightly more nit-picky than it appears at first glance:

  • it's important that the reserved bits are set appropriately (the variant and version).
  • it's important that the string representation is formatted correctly (following the ABNF outlined in RFC4122).
  • It's important that the remainder of bits are set using a cryptographically secure random number generator (a requirement that's easy to overlook. In a search of stack overflow, I found many examples using Math.random() which can lead to frequent collisions in UUIDs on some platforms.)

My opinion is that, even though UUID v4 is a concise algorithm: it's ubiquitous, so it would be convenient to provide a shorthand for developers; it's easy to screw up the algorithm, which would be good to protect developers from.

@martinthomson
Copy link
Member

(Warning: this is a pet peeve of mine. UUID is a bad meme.)

I mostly agree with @hsivonen. Having looked at the npm uuid module, it is doing everything right. If you need a UUID (you almost certainly don't), then that is where people should look. And they clearly are already. (The fact that that library contains anything other than v4 is annoying, but your minifier might take care of that for you.)

It's true that constructing a valid UUID is harder than just pulling from an entropy source. But it is almost certain that you don't need a UUID; 120 bits of random hex is superior in every way.

So this is a different question for me: is there value in identifying functions that are widely used and enshrining them in the platform. The benefit is that some people need to download less. In the short term, it has the opposite effect. Now the UUID library grows to include detection of the platform-level capability and functions to invoke that when present. Until all platforms include that function (it's the web, so that's longer than you might like), the library needs to remain. Only sites that are sophisticated enough to have browser- and browser-version -specific bundles will see the benefits even in the medium term.

@annevk
Copy link
Contributor

annevk commented Apr 19, 2021

@bcoe did you look into where browsers use UUID today? I found https://w3c.github.io/FileAPI/#unicodeBlobURL which doesn't specify the version, but presumably has to be 4 (filed w3c/FileAPI#163 on that). That also means the polyfill is really simple (but also very bad as it leaks a bunch of memory so please don't do this in production):

function uuid() {
  return URL.createObjectURL(new Blob()).split("/").pop();
}

If we already expose it in one place, I'd say we should also expose it directly unless there really are no use cases for it, but that seems improbable?

@ctavan
Copy link

ctavan commented Apr 19, 2021

Fun fact regarding the File API: Up until recently the spec showed a bad UUID version in one of the examples (fixed in w3c/FileAPI#151), so yet another example of how easy it is to get this wrong despite the fact that the UUID spec is so simple.


Now, to actually contribute to this thread:

I'm one of the maintainers of the uuid npm module. My thoughts regarding the arguments exchanged in this thread:

  • Historically (i.e. for the past 10 years), the biggest problem for the uuid library has always been the platform-dependent availability of a reliable CSPRNG. Working around these limitations and educating developers on the implications of using bad RNGs as a fallback remains an issue up until today. Getting this solved once and for all would be nice.
  • It's true that for many use cases that start from scratch, there might be better alternatives than UUIDs. However in practice UUIDs appear to be a well established format and downloads of the npm module keep on growing, so there doesn't seem to be a practical decline in interest or utility.
  • The fact that some Web APIs (FileAPI) already ship with UUIDs is another good argument for exposing it.

To summarize: Even though v4 UUIDs seem to be very simple, it seems to be hard to get them right in practice and given their ubiquitous nature I see value in having them added to the Web platform.

@bcoe
Copy link
Author

bcoe commented Apr 20, 2021

did you look into where browsers use UUID today

@annevk great question, I did a bit more digging through the Chromium codebase, and found these places where we rely on RFC4122 (I'm sure there might be more):

  • Payment Request API.
  • a few references to UUIDs in the Web Audio API, for behaviors such as generating track IDs (I didn't see this explicitly called out in the spec).
  • The Presentation API.

@cpeterso
Copy link

cpeterso commented Aug 3, 2021

Mozilla thinks crypto.randomUUID() is worth prototyping. I will post a patch in Firefox bug https://bugzilla.mozilla.org/show_bug.cgi?id=1723674.

An example of "UUIDs are hard" that is close to home: Gecko's nsUUIDGenerator on macOS delegates to Apple's CFUUIDCreate, which returns UUID look-alikes that don't actually set the UUID version or variant bits correctly. I discovered this when my patch to implement crypto.randomUUID() failed the WPT on macOS.

@annevk
Copy link
Contributor

annevk commented Aug 3, 2021

I'll close this as this is a small enough addition to not warrant a dashboard entry.

@annevk annevk closed this as completed Aug 3, 2021
@bcoe
Copy link
Author

bcoe commented Aug 5, 2021

@cpeterso @annevk awesome 🎉 thank you.

@cpeterso
Copy link

The crypto.randomUUID API landed in Firefox bug 1723674 and will ship in Firefox 95 (2021-12-07). 🚀

@bcoe
Copy link
Author

bcoe commented Oct 20, 2021

Awesome @cpeterso, I was following along in the bug, lots of excitement. Hope it lead to some worthwhile refactoring?

@cpeterso
Copy link

Awesome @cpeterso, I was following along in the bug, lots of excitement. Hope it lead to some worthwhile refactoring?

Yes, I plan to also update the JS code in Firefox and its tests to use crypto.randomUUID and retire Firefox's ancient (2005!) XPCOM API for generating UUIDs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants