-
-
Notifications
You must be signed in to change notification settings - Fork 89
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
How to properly use crypto.timingSafeEqual(a, b)
?
#39
Comments
The example in the README shows how to compare safely: https://github.com/jshttp/basic-auth#with-vanilla-nodejs-http-server |
You can replace the use of the function check (name, pass) {
var valid = true
// Simple method to prevent short-circut and use timing-safe compare
valid = crypto.timingSafeEqual(Buffer.from(name), Buffer.from('john')) && valid
valid = crypto.timingSafeEqual(Buffer.from(pass), Buffer.from('secret')) && valid
return valid
} The example just has the username / password you want to compare to in the code itself from simplicity, but you'd just inject it from where ever those are stored (like a database or something). |
Wouldn't it be more performant to not call |
(since we already call it here https://github.com/jshttp/basic-auth/blob/master/index.js#L78) |
I'm not sure. A benchmark would be able to answer that question, though. Also it looks like Why not just use the |
I saw this comment here https://github.com/suryagh/tsscmp/blob/master/lib/index.js#L5 and figured there should be a more modern solution using native Node methods is the only reason. |
The docs at https://nodejs.org/api/crypto.html#crypto_crypto_timingsafeequal_a_b have
Which doesn't mention passwords. This may be why it's a hard-to-use interface for variable-length data like passwords, while easy for fixed-length things like HMAC digests, etc. as the examples? Ideally when you're comparing passwords you wouldn't always want to directly compare the raw buffers, but make sure to run the password through a UTF normalization function. Because if the password the user has is |
I think another reason the Node.js docs for |
So that would meant to keep an attacker from reducing their attack complexity (by revealing the length of the password), you'd need to do something like hash the password before passing it to It would basically need to do everything the |
Yea, that looks good! Though if you're intending to make a PR to tsscmp than I'll need to find a different module to start advertising and using -- this module supports Node.js 0.8+ and the docs here will need to reflect that fact. |
And the several npm modules I have published will also need to move over to something else. |
@dougwilson what do you think about adjusting I'm not sure what version of Node actually was published with the |
Well, I'm not the author of that module, so you'll probably want to ask the author :) But that sounds like how I would normally do it, as a polyfill that uses it when there otherwise falls back for old versions. |
Looks like the method was added in |
Cool. If you're going to polyfill it, you don't even need to know when it was added -- check check if |
@dougwilson see suryagh/tsscmp@865e4d7 - any changes lmk! |
Cool. You may want to put a block around it to match the styling and move it after the length check (since |
done @dougwilson |
@dougwilson hey I'm curious if you had any security concerns/improvements to share here https://github.com/ladjs/policies/blob/master/index.js#L34-L48 - I'm not using |
So I don't see any use of the As for the comparison quality, as long as the database is using some kind of timing-safe comparison then it doesn't matter if the db is doing the comparison or the code is. I hope that helps! |
It does help @dougwilson - thank you. I noticed that Stripe also does this approach https://stripe.com/docs/api#authentication and so I wonder why they chose to use |
It's certainly possible. Of course, if just a single token is being provided, using |
* Added `crypto.timingSafeEqual` per <jshttp/basic-auth#39> * Fixed per comments at <https://github.com/jshttp/basic-auth/issues/39\#issuecomment-408716445>
Looks like |
Good to close, thank you |
Some people recommend And redundant for-loop check Here is my recommended version
There is also a good to know implementation of node-cookie package |
Hi @tranvansang I believe you opened this issue in the wrong location. Please file an issue (or PR) with |
It would be nice to pass an option
rawBuffer: true
or something to get the raw buffers returned asuser
andpass
instead of String's viatoString()
, that way we can usecrypto.timingSafeEqual(a, b)
for comparison?References:
https://nodejs.org/api/crypto.html#crypto_crypto_timingsafeequal_a_b
nodejs/node#17178
The text was updated successfully, but these errors were encountered: