-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Replace bcrypt with bcryptjs #2053
Conversation
🦋 Changeset is good to goLatest commit: 3eba7ab We got this. Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think doing this is good because removing native Node modules is Good(since it’s annoying pretty much everywhere) and a nice side benefit is that this lets us deploy to environments that are not Node.
From https://github.com/kelektiv/node.bcrypt.js/wiki/bcrypt-vs-bcrypt.js, it seems like the JS version is ~30% slower which I think is acceptable though the JS version does everything on the main thread while the native version doesn’t block the main thread which isn’t ideal.
I’m a 👍 but someone who is more familiar with bcrypt/password things should review this as well
@molomby I think you're best placed to review this and make an executive decision. |
I like the "just works" feature of using bcryptjs. The 30% performance loss isn't such a big deal, but the fact that it blocks the main thread is going to be a problem for some sites. It would be great if we supported both. |
Usually the deployment to cloud is on linux based servers (cheaper than windows counterparts) Dev environments on windows may use the instructions rather than the loss in performance. Native modules are higher performance and usually non blocking. Nodejs is single threaded traditionally, we should avoid adding overhead. bcrypt is like standard used in this scenario. We already have multiple overhead in process like ODM (knex/mongoose), graphql, keystone. |
Maybe somebody should contribute to bcryptjs and make it not blocking the main thread if that is possible? No doubt native modules are more performant. |
I have two internal sites running on windows, no issue with that. Just install windows build tools and run cmd with admin while installing dependencies or use developer mode in win10 to help you with windows setup. |
@OskarsPakers any reason for not using WSL. It's pretty much built-into Windows and makes these things a lot less painful. It's why WSL exists. |
I say this as a long time Windows user. |
FTR, I'm also using Windows to run KS and I've had no issues (though granted, I do have a dev environment set up). I'm not using WSL. |
Perhaps I was doing something really wrong, but that was a journey to the successful npm install.
Success! And I am not arguing that it is not possible to install keystone on Windows, but this is far from a simple npm install. And as bcrypt is the problem, switching to bcryptjs would make it easier. @MadeByMike I actually have subsystem for Linux and I use it, however, not all of my colleagues have it. Also switching to Linux is just running away from the problem. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a good idea.
Pro: Native JS
This is a real win. I've seen a stack of issues with node-gyp
over the years, not just on Windows but also with differences between MacOS dev and Linux production environments.
Con: Performance
The ~30% performance penalty (more like 0-20% in my testing) is a bit of a red herring. It shouldn't really contribute to production load due to the tune-ability of the workFactor
but it does reduce the security of the hashes in that, for a given workFactor
, brute-forcing a hash will be easier. But.. with a decent work factor and password complexity, that amount of compute needed to brute-force a hash is millions of CPU years. On that kind of scale we're worried about orders of magnitude, not double digit percentages.
Con: Thread Blocking
This is a problem, especially for a function that, by design, will usually take 100-1000 milliseconds to run. Remember, this penalty is paid both when generating and verifying hashes, making it even easier to (intentionally or otherwise) DoS a site by hammering on an auth mutation. It's also pretty hard currently rate limit auth mutations, exacerbating this risk (but we're working on it!).
So.. the ease of the native JS solution is great for small apps and better developer experience but, for larger or particularly security conscious sites, the compiled version is better. @sarneaud sums it up:
It would be great if we supported both.
Let's do that ☝🏼
These commits should be kept but let's also add a useCompliedBcrypt
option to the Password
field which reverts to requiring bcrypt
. Eg..
keystone.createList('User', {
fields: {
email: { type: Text },
password: { type: Password, useCompliedBcrypt: true },
// ...
},
});
The bcrypt
package doesn't need to be included in the package.json
; it can still be required if installed manually by the app developer. The docs would also need to be updated to cover the new option.
I think this makes sense and gives us the best of both worlds.. Does anyone else have thoughts on this proposal?
Another issue with using |
Closed by #2523 |
It is a nightmare to run this project on Windows as it uses bcrypt -> node-gyp which requires Python and Windows build tools.