You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm using uuid.Must(uuid.NewV4()).String() to generate random identifiers. I'm generating theses identifiers at a very low rate of a few dozen per days
Here are some non-random UUID that I got in the last weeks:
humans are bad at telling randomness. While it is extraordinarily, astronomically unlikely that you would have so many uuids with that many zeros, it is still theoretically possible.
Reacted by Ben Hutchison, Peter Hoeg Steffensen, Rollulus Rouloul, urpent, Martin Dørum, Robert L Pepka, applepi-icpc, Artur Kondas, debosmit, Luka Mesaric and 38 more
Reacted by Garet Halliday
Reacted by olarende-tink, Vignan Posham and jarupong pajakgo
In an IDs such as 80730000-0000-4000-8000-000000000000 there are ~14 consecutive bytes of zeros.. While a probability of something like 1/2**(14*8) isn't nil, it's still too low for my taste. Drawing theses IDs 5 times out of ~1000 isn't just bad luck. In real life, if it was possible, I would start mining bitcoins with my super powers!
Reacted by Nicnl, Andreas Tiefenthaler, Riku Lindblad, Michael K, Stephen, Russ Bodine, Gonzalo Spina, Rollulus Rouloul, Vic Perov, ayan george and 23 more
These UUIDs seem suspiciously non-random to me as well.
NewV4 gets its randomness from crypto/rand.Reader (and is basically a passthrough to populate a UUID). The code in NewV4 is really simple, I don't see how it could go wrong.
The only possibilities I can think of:
There is a bug in crypto/rand (seems unlikely).
Since crypto/rand.Reader is just a variable, some malicious/accidental code could be swapping it out for a less random io.Reader implementation.
Okay, I can reproduce it!
On my machine I have two separate processes: one webserver (ServerA) that calls uuid.Must(uuid.NewV4()).String() while simultaneously doing http requests to another webserver (ServerB) used for image resizing (imgproxy).
I instrumented ServerA with this code:
go func() {
for {
time.Sleep(1 * time.Second)
for i := 0; i < 1000; i++ {
u := uuid.Must(uuid.NewV4()).String()
if strings.Contains(u, "000000000") {
log.Fatal(u)
}
}
}
}()
Which runs without crashing if ServerA idle or handling standard requests. If ServerA is calling ServerB (to resize images), the ServerA immediately crash with a bad uuid.
I'll try to make a self-contained reproducer
Read reads up to len(p) bytes into p. It returns the number of bytes read (0 <= n <= len(p)) and any error encountered
Turns out, on some occasions Read would read less than len(u) bytes. I thinks uuid should use ReadFull instead of plain Read().
Reacted by Peter Stace, César Del Solar, Alexander Emelin, Cameron Ackerman, Ivan Kurnosov, Koichiro Okamoto, Gleb Stepanov, Nia, Alexander, Nitzan Zada and 55 more
Reacted by Cameron Ackerman, Gleb Stepanov, Nitzan Zada, Thibault NORMAND, Justin Lowery, Dmitri Shuralyov, Camille Louédoc-Eyriès, Rob van Hoose, Paul Tötterman, Russ Bodine and 8 more
@josselin-c Could you make a patch and see if you can reproduce the error with your script and ReadFull? I wonder if using ReadFull would outright return an error in this case, because there aren't enough bytes to read.
How is a critical bug like this still unresolved? Especially given that someone already did the work to fix it.
Reacted by David Alex Bielik, Jose Roberto Almaraz, Michael K, Thiago Escobar, Rob van Hoose, Paul Tötterman, Kartavya Ramnani, Tomasz Pietrek, urpent, Artur Kondas and 3 more
With BigQuery I tried to find github projects using the vulnerable version of this library and opened an issue on each of theses projects. At least the word is out and projects can act accordingly. I unfortunately don't have time to patch them all.
I hope there wasn't too many false positive 😄
Reacted by Will Navidson, Mattias Wadman, Riku Lindblad and Zachary Stewart
@josselin-c there's also talk in the Go community of taking over this project, and when we go this route I guess I'll need to go to every issue you opened and provide a correct the suggestions made to point to our version. Would you be willing to update all the issues you opened to mention that there may be a viable fork coming?
.I think this has incorrectly led some people to believe that 1.2.0 was not affected. This issue was created in March, and the latest release was in January same year, so unless @josselin-c used the code off the master branch and not 1.2.0, he would have experienced this issue on 1.2.0.
Currently, NIST lists 1.2.0 as excluded in the vulnerability scope of this project, which is causing us some compliance problems at the moment as the package is being used in a managed service we use at AWS. See https://nvd.nist.gov/vuln/detail/CVE-2021-3538
I have limited experience (alright, none) with Go, so please correct me if I am wrong. It seems various services/scanners out there do not agree if 1.2.0 is vulnerable or not.
If 1.2.0 is not vulnerable, there isn't any reason to panic at all, as the vulnerable code was then never released as a versioned dependency.
Edit: Okay, I read all of the comment I quoted. Since the replaced rand call is not vulnerable, 1.2.0 does not have any vulnerabilities. I have no idea why this vulnerability was ever published for 1.2.0 then.
Edit 2: I would like to stress that I am fully aware that this package is ancient and should not be used. However, I have run into compliance issues because it is still being used in code I don't control (AWS, thank you very much). I was/am trying to find out which way is up with this finding and how seriously to take it.
Activity
domino14 commentedon Apr 3, 2018
humans are bad at telling randomness. While it is extraordinarily, astronomically unlikely that you would have so many uuids with that many zeros, it is still theoretically possible.
josselin-c commentedon Apr 3, 2018
In an IDs such as
80730000-0000-4000-8000-000000000000there are ~14 consecutive bytes of zeros.. While a probability of something like 1/2**(14*8) isn't nil, it's still too low for my taste. Drawing theses IDs 5 times out of ~1000 isn't just bad luck. In real life, if it was possible, I would start mining bitcoins with my super powers!I don't know the root cause of this.
peterstace commentedon Apr 3, 2018
These UUIDs seem suspiciously non-random to me as well.
NewV4gets its randomness fromcrypto/rand.Reader(and is basically a passthrough to populate a UUID). The code inNewV4is really simple, I don't see how it could go wrong.The only possibilities I can think of:
crypto/rand(seems unlikely).crypto/rand.Readeris just a variable, some malicious/accidental code could be swapping it out for a less randomio.Readerimplementation.josselin-c commentedon Apr 4, 2018
Okay, I can reproduce it!
On my machine I have two separate processes: one webserver (ServerA) that calls
uuid.Must(uuid.NewV4()).String()while simultaneously doing http requests to another webserver (ServerB) used for image resizing (imgproxy).I instrumented ServerA with this code:
Which runs without crashing if ServerA idle or handling standard requests. If ServerA is calling ServerB (to resize images), the ServerA immediately crash with a bad uuid.
I'll try to make a self-contained reproducer
josselin-c commentedon Apr 4, 2018
Okay, I found the problem.
Here is the current NewV4 code:
Read()gives no guaranties about the number of bytes actually read. From https://golang.org/pkg/io/#Reader:Turns out, on some occasions
Readwould read less thanlen(u)bytes. I thinks uuid should use ReadFull instead of plain Read().domino14 commentedon Apr 4, 2018
@josselin-c Could you make a patch and see if you can reproduce the error with your script and
ReadFull? I wonder if usingReadFullwould outright return an error in this case, because there aren't enough bytes to read.domino14 commentedon Apr 4, 2018
One more thing that is interesting to me is the fact that the UUIDs you posted are not of equal length.
Fix potential non-random UUIDs
mikesun commentedon Jun 1, 2018
So it looks like this commit introduced the bug: 0ef6afb
Prior to that commit,
rand.Read()was used, which is a wrapper that usesio.ReadFull(): https://golang.org/pkg/crypto/rand/#Readcameracker commentedon Jul 10, 2018
How is a critical bug like this still unresolved? Especially given that someone already did the work to fix it.
josselin-c commentedon Jul 11, 2018
With BigQuery I tried to find github projects using the vulnerable version of this library and opened an issue on each of theses projects. At least the word is out and projects can act accordingly. I unfortunately don't have time to patch them all.
I hope there wasn't too many false positive 😄
theckman commentedon Jul 11, 2018
@josselin-c Did you confirm that these project were using a vulnerable version, or did you just fire from the hip?
theckman commentedon Jul 11, 2018
@josselin-c there's also talk in the Go community of taking over this project, and when we go this route I guess I'll need to go to every issue you opened and provide a correct the suggestions made to point to our version. Would you be willing to update all the issues you opened to mention that there may be a viable fork coming?
josselin-c commentedon Jul 11, 2018
I used theses query:
uuid.Must(uuid.NewV4())has been introduced with the vulnerability so matching this expression should be correct.Same thing, NewV4() that returns an error has been introduced with the vulnerability, matching this expression should be correct as well.
josselin-c commentedon Jul 11, 2018
Here is the projects list: https://gist.github.com/josselin-c/c1bda90ba538c65a5b8062aa2db0c386
62 remaining items
Update dependency to generate UUID in benchmark
Update dependency to generate UUID in benchmark
Migrate to use github.com/gofrs/uuid
build(deps): bump github.com/satori/go.uuid module
austinmhyatt commentedon Aug 24, 2021
What's the fix here? :)
Searching for upgrade option for CVE-2021-3538
rkuris commentedon Aug 24, 2021
Switch from unmaintained github.com/satori/go.uuid to github.com/gofrs/uuid
austinmhyatt commentedon Aug 24, 2021
Thanks! @rkuris
chore: switch from satori/go.uuid to google/uuid
Override github.com/satori/go.uuid revision for transitive deps (infl…
nickdnk commentedon Sep 18, 2024
The code was already vulnerable in the released version 1.2.0, as the same call was made in thesafeRandomfunction. See 0ef6afb#diff-0d0495ad16c6f603876bbf484c43b549f53d0b33d4cd74c908b0ee95a94369eaL200..
I think this has incorrectly led some people to believe that 1.2.0 was not affected. This issue was created in March, and the latest release was in January same year, so unless @josselin-c used the code off the master branch and not 1.2.0, he would have experienced this issue on 1.2.0.Currently, NIST lists 1.2.0 as excluded in the vulnerability scope of this project, which is causing us some compliance problems at the moment as the package is being used in a managed service we use at AWS. See https://nvd.nist.gov/vuln/detail/CVE-2021-3538
I have limited experience (alright, none) with Go, so please correct me if I am wrong. It seems various services/scanners out there do not agree if 1.2.0 is vulnerable or not.
If 1.2.0 is not vulnerable, there isn't any reason to panic at all, as the vulnerable code was then never released as a versioned dependency.
Edit: Okay, I read all of the comment I quoted. Since the replaced
randcall is not vulnerable, 1.2.0 does not have any vulnerabilities. I have no idea why this vulnerability was ever published for 1.2.0 then.Edit 2: I would like to stress that I am fully aware that this package is ancient and should not be used. However, I have run into compliance issues because it is still being used in code I don't control (AWS, thank you very much). I was/am trying to find out which way is up with this finding and how seriously to take it.
nickdnk commentedon Oct 21, 2024
Version 1.2.0 of this package is no longer listed as vulnerable. NIST have revised their publication.