Christoph’s Short Guide to Keeping Your Web App’s Users Secure
- Do not store any password at all. No password, nothing that can be stolen. A password-less login is easier to make than you think. You will require people to submit a valid email to use your service. Offer users to send them a one time password over email when logging in. The email contains a one time password and a link which conveniently logs the user in. This is the same flow as a password reset, which you will need anyway in your app’s login system. This method tends also to offer good signup conversion rates, because an email is the sole required information.
- Do not restrict maximum password length in password fields. A long password is a secure password. Also allow use of all characters, including spaces. Do not discourage people of using long passwords.
- Do not use constraints, like “Has to contain at least one number, an uppercase letter and a special character”. These constraints do not lead to memorable passwords. Therefore most people will keep them short to be able to remember them. Or worse: they store them in an unencrypted Excel sheet on their computer, or a post it beside their screen. And short passwords are not secure. Period.
- Encrypt passwords with bcrypt before storing them somewhere. Never store passwords in plaintext on a server. Never.
- Point users at Diceware and encourage usage of password managers. Diceware is a simple process to make memorable passphrases, which are long, and thus secure. But using the same password for more than one service is not secure as well. Use a passphrase generated with Diceware to secure the password manager (1Password ist great). Then employ your password manager to generate a unique password for each service. Also 1Password is capable of showing you alerts when a service’s security has been breached and you should change your password.
- Offer Two-Factor Authentication. It’s the only thing that stands in the attacker’s way if the user’s email is compromised. Two-Factor means that a second, unique, one-time-use password (sent by SMS, or generated by your phone) is needed when logging in. It also means that a password reset is only possible with a special backup code, which should not be stored on a computer. This also precludes a reset with security questions.
- Never let the user reset a password by answering security questions, like “What was your favorite teacher?”, or “What was your mother’s maiden name?”. The answers to these questions can be easily researched online or obtained by doing some social engineering. I understand that you need a way to let users reset their passwords when they lost access to their email. Provide a secure reset token (similar to backup codes offered by Two-Factor systems) and advise users to store these tokens not on their computers or in plain sight.