I’m not sure if this is the correct place to ask this, so if there’s a better community please direct me to it.
I’m making a web app that I plan on hosting. Users will be able to create an account on the website. The only information about the user themself I store is email and an argon2 hash of the password. All the other information stored about a user’s account is specific to and only makes sense in the context of the app.
Now, while I only have one piece of PII, I’d prefer it to be zero. Ideally I’d replace the email with a username for the purpose of uniquely identifying users. However, there’s one problem: I want to be able to send an email to a user if they forget their password so they can reset it. I don’t know if there’s a way to do this without storing their email.
Is there a way to do the mentioned functionality without storing PII? Alternatively, is there another way of handling a user forgetting their password that doesn’t require them to remember anything and doesn’t need PII?
You could use system like SQRL (https://sqrl.grc.com/pages/what_is_sqrl/) for login that does handle “password” resets without email.
You could use argon2 to hash the email as well, you ask user for email on “I forgot my password” page, argon2 it and compare (like with password). At this stage you will know the email and that is the same as set during registration, to send the reset code.
Both of those sound like good suggestions. Thanks!
I like the idea of hashing the password reset email. But also consider if it can be made optional. If you are going this route you will need a username anyways (you can’t reasonably let people login with email when it is hashed like a password). In this case some users may prefer to just have no password reset options. Password reset is just a weakness in the security of the system. For most users it is a worthwhile weakness but a lot of users would prefer to be locked out of the account than letting someone gain access.
Unlike passwords that are hopefully random most user’s emails are “public” and usually low entropy this means that hashing it is good obscurity but it isn’t enough to truly hide it because someone can build a dictionary of possible emails to check.
You’re approach seems like a good one. I looked into SQRL and while it’s fast and secure, it seems obscure, and asking a user to set up a type of login credential that they’ll use for multiple sites for the rest of their lives seems like a pretty big commitment that I don’t want to have to put my users through.
You can generate “shadows” of the password with a scheme like Shamir’s Secret Sharing Scheme. These shadows can then be distributed to “unrelated friends”. Whenever you loose your password, you ask your friends for the shadows you gave them earlier and you can recover the password from the secret recovery procedure of the scheme. This prevents any single “friend” from recovering your password while allowing password recovery.
You need some kind of identifying information in order to restore a password without risks. It must be something that both you and the user remember, and that either nobody else know, either some user address unique to them.
One alternative address to email is phone number, but that’s potentially more identifyable and intrusive than email.
You could also generate an ID that you store hashed and send it to the user email at sign up time, and then ask the user to provide you this secret if they want to change the password. Actually, it would be a recovery password sent in plaintext to the email. Maybe showing it just once in the webapp and asking strongly to save this code safely? It would be equivalent as asking the user to save their password safely…
What do you think?
I just ended up storing a hash of the email.