mozilla / standards-positions

https://mozilla.github.io/standards-positions/
Mozilla Public License 2.0
658 stars 72 forks source link

Cryptographically secure random UUIDs #511

Closed bcoe closed 3 years ago

bcoe commented 3 years ago

Request for Mozilla Position on an Emerging Web Specification

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 commented 3 years ago

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 commented 3 years ago

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 commented 3 years ago

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 commented 3 years ago

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 commented 3 years ago

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:

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 commented 3 years ago

(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 commented 3 years ago

@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 https://github.com/w3c/FileAPI/issues/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 commented 3 years ago

Fun fact regarding the File API: Up until recently the spec showed a bad UUID version in one of the examples (fixed in https://github.com/w3c/FileAPI/pull/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:

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 commented 3 years ago

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):

cpeterso commented 3 years ago

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 commented 3 years ago

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

bcoe commented 3 years ago

@cpeterso @annevk awesome 🎉 thank you.

cpeterso commented 3 years ago

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

bcoe commented 3 years ago

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

cpeterso commented 3 years ago

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.