-
Notifications
You must be signed in to change notification settings - Fork 14
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
Fix potential vulnerability in use of the rand.Seed #2
Conversation
According to webauthn spec. the challange needs to be hard to guess otherwise the protocol is vulnerable to reply attack see: https://www.w3.org/TR/webauthn-2/#sctn-cryptographic-challenges > In order to prevent replay attacks, the challenges MUST contain > enough entropy to make guessing them infeasible. Challenges > SHOULD therefore be at least 16 bytes long. Initating with the random seed with time makes it easy to guess after a restart. The space of seeds can be quickly enumerated, because time has lager resultion than nanosecods. See this more details: https://github.com/Quiq/webauthn_proxy
Thanks, we will review this for inclusion |
Thanks @PiotrCzapla, Thank you for the links provided; I concur that using time as an entropy source is at best sub-optimal as time is predictable and thus leaves the resulting encryption weaker as a result. Taking from the spec linked:
The proposed code moves from using This should result in a greater entropy for the RNG, as the next improvement for this (should time allow) it would be advisable to use purely the |
I further wrote a brief test (please forgive my terrible golang):
To produce sample I ran the following for i in {1..100000}; do ./test >> ./distribution.log; done Then ran in another shell:
First 10 bytes of this seed are the current time to the second: Extracting the values to individual files.
"new" method Estimated Entropy"old" method estimated EntropyEntropy conclusionThere is an improvement over the original time based seed method; future iterations should seek to leverage |
@PiotrCzapla One question, can you explain where you're using |
For completeness I implemented https://github.com/duo-labs/webauthn/blob/1daaee874e43b3bc324ade89467c603b5016d4b9/protocol/challenge.go for the "proof"; the results of which are as follows: test.go
produce sample set
extract sample set
evaluate sample setold cyberchef entropynew cyberchef entropynew32 cyberchef entropyConclusionUsing a purely this PR will improve the Entropy shannon scale score from 3.199 to 3.524; I'll take a look at submitting a PR to get the index to the ~6.02 value shortly. |
Looks good. @Oneiroi has found a way to increase the entropy significantly so we'll merge this in and then he'll make his change as well. Thanks a lot @PiotrCzapla ! |
thanks @PiotrCzapla ! |
Guys, The go docs confirm this:
So we should use crypto/rand to generate the challanges. It uses /dev/urandom, which cannot be exhausted and is implementing CSPRNG (Cryptographically secure pseudo-random number) kernelside (https://stackoverflow.com/questions/13017023/how-can-i-exhaust-dev-urandom-for-testing) An alternative that won't block is to get some user space implementation of CSPRNG. But I can't find any reliable library for go :(
@Oneiroi do you have better idea how to generate the challanges? |
I was wondering that my self, I've made the PR on iPad so I've copied the code verbatim from stack :). |
If anyone is interested this is a really good explanation of /dev/urandom and /dev/random. So we should be safe using crypto/rand: https://www.redhat.com/en/blog/understanding-random-number-generators-and-their-limitations-linux |
I created #3 this implements the challenges in a more secure fashion, admittedly there's issues with these functioning right now I suspect this is to do with a need to update the JS to accept the change from integer based challenges to the base64 encoded version in #3 this is using Now Just need to fix the JS (is my gut feeling) to make this improvement viable 😅 |
According to webauthn spec. the challange needs to be hard to guess
otherwise the protocol is vulnerable to reply attack see:
https://www.w3.org/TR/webauthn-2/#sctn-cryptographic-challenges
Initating with the random seed with time makes it easy to guess after
a restart. The space of seeds can be quickly enumerated, because time
has lager resultion than nanosecods. See this more details:
https://github.com/Quiq/webauthn_proxy