Currently, we use SHA1 for encrypting users' passwords. BCrypt is more secure so we will move to it.
Reasons why are outlined in the MOVE TO BCRYPT Trello card, especially the comment by Sherman Boyd. We're continuing the conversation in this issue.
As Sherman points out, the code change will be easy but migrating users will be hard. We cannot invalidate all current passwords, even with advanced notice, because many users would not read the notice and having many unable to log in with their expected passwords would be a support and publicity nightmare.
Perhaps we can have both schemes in use in the codebase at the same time, with each user account having a flag to indicate which they use.
Assuming we do the password-update-on-login idea, these ideas become less relevant (although note that some users might not log off and on for weeks):
I suggest that accounts that haven't been used for more than several months could be changed to the new scheme immediately. It's likely those users would have forgotten their passwords anyway (admittedly I'm ignoring those who use password managers).
Any other suggestions / comments?
EDIT: Note @crookedneighbor's comment below about changing the code to use hashedPassword instead of hashed_password, and storing the BCrypt password in a new hashedPassword database field. We can probably use the existence of that field instead of the flag mentioned above.
Note that when users change their passwords, they can enter the same password as before. It would then be encrypted in the new scheme and they wouldn't have to remember a new password.
The simplest approach might be to go with the two-schemes system (all new users use BCrypt, all users who change passwords use BCrypt, everyone else keeps their old SHA1 password) but with no user notification, and then later we can worry about whether we ask/encourage/force users to change.
Could we also have it swap out the password for new hashed one when the user logs in?
omg genius
I'm updating my first post to include that so we don't forget it and so it looks as if I thought of it. ;)
For this, we should make the snakecase hashed_password a camelcase hashedPassword.
With v3, eslint will fail the build for using snakecase. I can set it to ignore that specific line (see https://github.com/HabitRPG/habitrpg/pull/6203/files#r44226378), but it'd be better to not have to do that. Since this work needs to be done anyway, we might as well do that change now, rather than do a migration later.
I'm thinking that whenever the new Bcrypted password gets saved, it gets saved to the new hashedPassword instead of to hashed_password, and then once everyone is converted over we can remove hashed_password from the model.
You could also do the following:
If they forgot their password:
This is a very smooth way of handling it with only minor, if any, annoyance. Most people will just take a few seconds, log in, and won't even notice the nice security benefit.
The only people I see needing help are those who forgot their password and no longer have access to their e-mail account.
Being logged out automatically from Habitica isn't something that typically happens, so if all non-facebook players were logged out at once, there'd be questions in the Tavern and social media about what had happened, and then a lot of "me too" posts. It would make Habitica seem buggy.
Also there's likely to be more players than you'd think who have lost access to their email accounts or who mistyped their email addresses when they registered - we get a surprising number of support requests about that. If we had to handle requests from all of those players at once, it would be overwhelming.
I think a slower process of converting passwords as people log out and in manually in their own time is all that's needed at first. After a few weeks, we can assess the accounts remaining to be converted and make plans for them then.
I agree. Logging out everyone at once would be a support nightmare.
I think we should just have some friendly reminders to do it, and maybe some kind of incentive?
If we can get the majority of active users to switch over voluntarily, then we can discuss logging the rest of them out.
The tags idea is a good one. It doesn't hurt to look at the future too, when someone figures out an attack against bcrypt. I was looking into how Linux handles this. Linux predates most hashing algorithms, so they had to figure out a future proof way handle hashing algorithm changes. Basically they embed a tag in front of the hash:
Example hash: $1$Etg2ExUZ$F9NTP7omafhKIlqaBMqng1
$1$ = MD5
$2$ = Blowfish
$2a$ = eksblowfish
$5$ = SHA-256
$6$ = SHA-512
You could add the tags (not necessarily in the hash), and support multiple algorithms, with a 'default' algorithm.
The switch should be transparent to users, changing the passwords hashes when they login is a great way to do it. They don't really care about password hashes, so best not to involve them. You'll get the most active users, the valuable ones right away. Add processes to kick users after being logged for an extended period of time, and a process to prune / retire inactive accounts. Eventually you will get them all.
The upside to this approach is that you could just code it, implement and forget it. Logging someone out eventually is probably a good thing in general, and so is pruning inactive members. Downside is more code, complexity. Some exposure over time, but they have to get your hashes first, before they can start cracking them.
I love the idea of tags or similar - that's very clever! I've added a note about it to the top post.
I'm glad to see this is being worked on - thank you! @crookedneighbor 's idea of offering incentive would definitely speed compliance (assuming the infrastructure exists to offer the user a piece of gold for doing a site task). If it takes several months to slowly migrate the rest, so as to not overwhelm support, at least it's done after those several months! Unfortunately at $dayjob I've been telling people "when your password database is stolen" rather than "if" lately.
We could also make a modal pop up when the user first loads the site prompting them to update their password. (They could even do it right from the modal)
A modal is a nice idea! It might be the only incentive we need to get many of the users converted. Although I'd like to see it implemented a couple of weeks or more after the feature where their password is automatically updated when they log in. We're bound to get questions about why the modal exists (even if the modal explains why itself!) and reducing the number of people who need to be shown the modal would help with that.
I've added the idea to the top post.
Unfortunately at $dayjob I've been telling people "when your password database is stolen" rather than "if" lately.
Yeah, additionally the exposure goes beyond habitica, surely there are users that use the same password for everything; Amazon, Paypal, online baking etc. With that in mind sooner sounds better than later.
PR in progress: https://github.com/HabitRPG/habitica/pull/8446
Most helpful comment
PR in progress: https://github.com/HabitRPG/habitica/pull/8446