-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Security: Use crypto.randomBytes, not Math.random #832
Conversation
Using the synchronous version of |
@JoshuaWise incase a cached _randomMask like |
@sequoiar I think that might be a premature optimization. Caching random bytes might be something we do in the future, but we should avoid unnecessary complexity before we've measured the performance impact. As for using the synchronous vs asynchronous version of The actual generation of the bytes (after it's done waiting for entropy) is likely several orders of magnitude less than a few milliseconds. |
@JoshuaWise You may be misinterpreting the docs. the synchronous version is almost guaranteed to never cause a bottleneck, but in the rare cases that it does (i.e. you're generating gigabytes of random data in another process), it may take a few milliseconds to get a normal about of random re-seeded. On first system boot (or when there is no cached random data from a previous boot - not the case to optimize for), it may take slightly longer. If you search around a little bit on the net you'll find people complaining about cases where they run out of system entropy and it's generally A) they're using Arch Linux, haven't started the entropy daemon yet, and are generating large ssh keys as part of setup or B) are generating gigabytes of random data for some particular purpose. If a benchmark shows that 4 bytes of random data a few thousand times every few minutes is killing performance I would not disbelieve it, but I wouldn't jump to assuming that a normal use case would cause unusual performance behavior. |
Also, the very idea of generating enough random masks to deplete the entropy pool is counter intuitive. How would you be sending and receiving all of this websocket data and not generating entropy from disk and network access in that process? |
Ah, you're right, I did misread the docs. Thanks for pointing that out. I'll let the other maintainers chime in if they have any thoughts, but otherwise, LGTM. |
It would be nice to see a benchmark but I think it makes sense. |
IMHO, it makes sense to leave it as it is, just in case the way the mask is returned changes again. |
The function is probably inlined so yeah there is no overhead but it triggers my OCD 😄 |
I agree with @ericmdantas. The function is certainly inlined, and I like self-documenting code. |
@coolaj86 |
Looks like there's no noticeable difference - just a little noise. node bench/speed.js
node bench/sender.benchmark.js
|
Yeah LGTM. I'll leave this open for another day to give other maintainers the opportunity to chime in. Otherwise I'll go ahead and merge tomorrow. There's a 5% performance loss on the sends that aren't even masked, meaning we can expect at least 5% of random noise. So the 10% loss on the masked sends doesn't worry me. Especially since masked sends are only client-to-server, which are certainly the least important in terms of performance. |
As for the caching, we're not allowed to cache masks because they should be unique each time as far as i'm concerned. As for the sync generation. I would prefer that is done async to prevent event loop blocking when a lot of messages are being send. |
(╯°□°)╯︵ ┻━┻ My plea has fallen upon deaf ears.
|
I think it would be nice for this to be merged before the next big release. |
@JoshuaWise I agree. |
Merged as 7253f06. |
@coolaj86 @lpinca Would you consider backporting this for a 1.1.2 release? That would allow projects that still need to support Node < 4 to get this security patch. I forked and patched the 1.1.1 code here: https://github.com/sgress454/ws/tree/backport-crypto-patch-to-1.0, but not sure if there's any way to make a PR out of that unless there's a 1.x branch to submit it against. |
@lpinca Let's do a 1.x release. |
I've just created a v1.x branch, can you please submit the PR against that branch? |
Thanks! |
If we are going to release 1.1.2 I think it makes sense to also backport #810. |
Depending on the JavaScript engine (node now runs on Chakra and V8) Math.random can be anywhere between extremely insecure (v8's implementation has collisions at around 24,000 cycles) and cryptographically pseudo-random.
However, using crypto.randomBytes() directly ensures that the secure version is always used.