Web identities and authentication center around email accounts. The assumption is that one email address belongs to one person, anyone who has access to it can be trusted, and that all email accounts are secure. Because of this, if you forget your password for a web service, your email account is the key to getting the password reset. When the assumptions above are challenged, you can lose a lot.
There are some flaws in the above assumption:
- Some organisations, particularly universities, do the wrong thing and reassign email addresses after a period of time: a few years after you leave university, someone else could be assigned your old email address. If you created web accounts using your university email account, the person with your old email address now has access to those accounts.
- Domains change hands. If you sell or let an old domain name lapse, whoever buys that domain now has access to any web accounts you created using an email address at that domain.
- Unencrypted emails are readable as they travel across the network. While it's unlikely (but not impossible) that someone would sniff the contents as the message travels between internet providers, connections over wireless and to email servers are often unencrypted and easily sniffable. Using SSL to encrypt connections and GPG to encrypt emails can help here, but...
- Email servers are insecure. From XSS and CSRF holes in webmail, to security holes in email handling daemons, to security holes in any one of the processes or web pages running on a server, it can often be possible to access email files stored on or delivered by the server.
Because of these flaws, the authentication process needs to be designed with the assumption that the email being sent is insecure, either now or in the future, and that any breach of security should be immediately visible. Here's a summary of the process for resetting a password:
- A user says 'I forgot my password' and enters their email address. [If there is no account for that email address there's often a message asking the user to enter an existing address: this could benefit spammers who could use this to check whether an email address is valid, so some sites, such as Joost, use captchas to minimise this and other abuse.]
- If the account is particularly sensitive, such as for a bank, resetting a password may require secondary authentication, such as a code sent by post or to a mobile phone, or the answer to a security question.
- An email is sent to the address given, explaining that someone has requested a password reset, that nothing has happened so far and the message should be ignored if they didn't request it (the user's account will be unaltered until further action is taken). The email gives the IP address of the person who made the request, so abuse can be tracked. A link is given, which should be followed in order to change the password. This link can only be used once and expires in 48hr, so if someone gains access to the user's email account in the future they won't be able to use this link to reset the password.
- The user follows the link and chooses a new password, which is submitted using SSL (HTTPS). While typing, the password is vulnerable to keyloggers, so banks may use mouse clicks on a virtual keypad, but for most sites this is too inconvenient.
- The web application stores a hash of the user's password in a database. The plain-text form of the password should not be retrievable, as this would allow anyone who can access the database (whether legitimately or not) to read the password and try to use it to access the user's accounts on this or other sites without their knowledge. The hash should be non-standard, maybe using a unique key, so can't be easily looked up in a rainbow table.
- A confirmation email is sent to the user's email address. This email does not contain the new password, so if someone gets access to this email account in the future they won't be able to use the password. In fact the password is never displayed at any point. The text of the email explains that if the user has received this email without requesting it, their account has already been compromised and they should change their password immediately. The email also gives recommendations for password strength.
By connecting to their email server or webmail using TLS/SSL (HTTPS), the user can prevent anyone from obtaining this link while the email is in transit. Once the link has been followed it becomes invalid, so no-one can use the same link in the future: if anyone was sniffing the user's email and tried to use the link already, the user will notice as the link will no longer work.
Drupal does pretty well at this (the explanatory text could be better), but the best practice I've seen recently is from DynDNS, example emails from which are copied below (I've replaced some information with placeholders in <> brackets.
----
Example email from DynDNS (Step 1):
----
Subject: Password Reset Request
From: DynDNS Support <support@dyndns.com>
Dear Valued Customer,
Someone has requested that the password for your account,
username <username>, be reset.
If you did not make this request, please simply disregard this
e-mail; it is sent only to the address on file for your account,
and will become invalid after 48 hours, so you do not have to
worry about your account being taken over.
To choose a new password, please go to the following URL:
https://www.dyndns.com/account/resetpass/<unique-key>
This request originated from <IP address>
Your username is <username>
Sincerely,
The DynDNS Team
----
Example email from DynDNS (Step 2):
----
Subject: Successful Password Change
From: DynDNS Support <support@dyndns.com>
Dear Valued Customer,
Your password for the DynDNS login system has been successfully
changed. The new password is not printed here to protect your
privacy, and your username is confirmed below.
Username: <username>
If you have not requested this change, your account most likely
has already been compromised. You should immediately request a
password reset at https://www.dyndns.com/account/resetpass/ to
change your password to a new, secure value. You should only
ever login to our account through secured (https) links, and you
should not use a dictionary word as your password.
IMPORTANT NOTE: You must keep the e-mail address we have on file
for you up-to-date. Any accounts which cause bounced e-mails
will be terminated.
Thank you for choosing Dynamic Network Services, Inc.
Sincerely,
The DynDNS Team
----
This doesn't handle the cases where control of your email account has been handed over to someone else: in those cases perhaps online accounts should require additional security for password resets if they've been inactive for more than a year. It could also be easier to delete accounts that you own (with an appropriate retention proviso in case of malicious deletion requests), so you can clean up before leaving an old email address behind.