Consider this scenario: you build a Web site that requires some kind of user log-in. You allow users to create usernames and passwords and require a valid username and password to get in to your site. But is your Web site authentication scheme secure? Every time I register at a site, I marvel at the consistently laughable - sometimes pathetic - security among even the world's largest Web sites. As the Web becomes more a part of our personal lives, the threat of fraud and identity theft grows accordingly.
Inadequate user security is a problem that Web developers must address. Perhaps it is lack of standards. Perhaps it is a lack of auditing. This article addresses both of those issues by establishing a standard audit procedure by which to measure your own security. Test this list of questions against your own Web site's authentication scheme and see how it stands.
Does the system require both a username and password?
This one should be a no-brainer, but occasionally I run across a site that requires a password but no username. The problem with this arises if the user tries to set a password that another user has already used. You will have to notify the person that password is already taken and then they will know someone else's password, which, given that usernames aren't being used, may give him ready access to the system.
Does the system allow for, encourage, or enforce strong passwords?
If your security system depends on passwords, then you can only have strong security if you have strong passwords. Therefore, enforce minimum password lengths and do not allow passwords that closely match the username. Using numbers and punctuation characters will make a password stronger, but you can also encourage longer passwords, which are just as effective (see Ten Windows Password Myths). You can also make passwords stronger by allowing spaces and encouraging users to choose pass phrases. Furthermore, allow users to use any keyboard character in a password; don't limit them to characters and numbers. Also, set liberal limits on maximum password length: 128 characters or more.
AOL's ScreenName - which includes AIM, Netscape Network and Compuserve - allows passwords as short as three characters but will allow a maximum length of 16 characters, which is far too liberal on the minimum length and too restrictive on the maximum length.
Does the system allow for password aging and enforce a password history?
Hotmail was born July 4th, 1996 - nearly seven years ago. That's almost 2,500 days at the time of this writing. Now ask yourself, how many of those millions of early Hotmail users do you think still use the same password they set nearly seven years ago? If you do not want to enforce password aging on your Web site, you should at least occasionally remind people how old their password is.
Password histories prevent users from changing their expired passwords, then changing them back again. You do this by saving the last few passwords a user uses. Of course, users can circumvent this by changing their password a few times, filling up the password history, and then setting it back to the original. You can counter this by either having unlimited password history entries or enforcing minimum time periods before users can change their passwords again.
Does the system use easily-guessable or default usernames and passwords?
You should avoid using common, easily guessable, or sequential usernames. Avoiding these will help limit exposure to attacks against specific accounts. You should never assign default or easily guessed passwords to any account; instead, ask users to select their own passwords.
Is it possible to harvest usernames from the application?
Some applications allow the guessing, or harvesting or usernames from your application. If an attacker is able to collect a list of usernames, he can launch a brute-force attack looking for weak passwords. Revealing usernames can also lead to other problems. For example, the forums at groups.msn.com show the user's name with each post. Of course, you would want to know each user's name, but consider that having a user's name means you also have their e-mail address and Instant Messenger name. A spammer could easily spider the site and gather millions of account names.
Do error messages provide too much information about usernames or passwords?
Once I was logging into an online banking site, but mistyped my password. I got an error message stating that my password didn't match. It also told me that passwords are four characters long, can only be upper case letters or numbers, but cannot start with a number. While that information may be useful, it also lets a hacker know the limits of the password key space. Another Web site issued a notice that my password was made up of the last four digits of my Social Security number, which is hardly private information. Make sure your error messages do not reveal too much information about the nature of a password.
Does the module detect and prevent brute-force guessing of usernames or passwords?
To prevent intruders from launching brute-force password guessing attacks, take measures to detect and prevent these attacks. To reduce exposure to brute-force attacks, lockout accounts with high numbers of failed logins and be aware of total failed logins across the system.
Does the source code contain any hard-coded username or password checks?
If it does, remove them.
Does the system make use of obscurity to authenticate users?
I once saw a system at an e-commerce Web site that allowed users to access private files only if they knew the long, obscure URL of the files. This is similar to hiding a key under a doormat: you are safe only if people don't know you hide the key under the doormat.
Can users change their username?
Occasionally, users may need to change their username for one reason or another without creating an entirely new account. Some systems, however, do not allow this because the username is the primary key in the database. eBay allows users to change their username so they won't lose the hard-earned feedback on their account. On the other hand, you must carefully consider the effects of allowing users to do this. A user may want to change their username to avoid a bad reputation, and you certainly do not want to facilitate that.
Do you require e-mail addresses for usernames?
Microsoft's Passport requires that you set your username to a valid e-mail address. Usernames that are e-mail addresses may allow spammers to harvest e-mail addresses and make it difficult to change a username. It also forces users to change their username each time they change their e-mail address. You should allow users to use e-mail addresses for their account names, but do not force them to do so.
Do users automatically receive online accounts even though they will not use them?
Many banks automatically provide online account access for all their account holders, even if those account holders don't need to access their accounts online. Maybe these customers don't have Internet access, don't want to bother with learning how to use it, or don't trust their bank's security. Providing access that is not used can be dangerous because it results in unattended online accounts and many users who are not even aware that they have even have online accounts.
Can users easily change their own passwords?
If you don't make it easy for users to change their passwords, they are less likely to do so. Changing passwords should be an obvious and convenient feature of any authentication system. One thing you can do for users when their password gets old is to put a small reminder at the top of the page, including a link to change their password.
Are users required to re-authenticate before and after changing a password?
When you allow users to change their passwords, have three fields: the old password, the new password, and verification of the new password. This prevents intruders from changing passwords on hijacked accounts. Say, for example, that someone logs in to a Web site, and then leaves the site to browse to other sites. Suppose then that they leave their desk with the browser window open. Someone else may be able to browse back to the site, change the user's password, and then have full control of the account. There are also situations where stealing a cookie or other authentication token allows someone else to hijack a user's account. If you always prompt for old passwords before setting new passwords, you will reduce these types of attacks because the attacker must know the user's actual password.
After users set a password, you should expire any session tokens and require them to log in again. Recently a friend received an e-mail stating that there was a problem with his eBay account. The e-mail had a link to log in to eBay to fix the problem. He clicked on the link, entered his username and password, but immediately realized that he might have been tricked into logging in to a fake site. Without delay, he changed his password, but then saw bogus auctions appearing on his account. Next, he found that his contact e-mail address had been changed. eBay's fraud detection kicked in and suspended his account, canceling over 250 active auctions. Even though he quickly changed his password, it was too late; a hacker had already logged in and had full access. In fact, the intruder was able to do anything he wanted until he closed the browser window or logged out. By forcing a logout after changing a password, you can terminate any active sessions.
Finally, when changing a user's password, always e-mail them a confirmation that the password has been changed, and perhaps include the IP address that initiated the change.
Does the system allow for password retrieval?
As an alternative for allowing users to retrieve passwords, you should instead have them reset their passwords. Allowing users to retrieve passwords means that passwords are retrievable; they are stored in a database table in either plain text or using reversible encryption.
Consider this example: a hacker breaks into someone's computer and has full access to the victim's PC. The hacker sees that the user has an online banking account. So he logs in to the banking site, clicks on the "Forgot My Password" link and waits for an e-mail. As soon as the mail containing the password comes in, he deletes the mail and logs in to the site. The user never knows that the password was compromised.
The best way to deal with lost passwords is to reset the password and e-mail the user a secure link back to your Web site. In the e-mail you should clearly state that a password reset was initiated and from which IP address it was initiated. Once they click on the link and have connected back to your Web site, they can select a new password for their account.
Does the system require some form of verification before resetting a password?
Another way to prevent the above scenario is to always prompt for some kind of personal information before sending an e-mail for a password reset or information request. You cannot assume that a user is the only person who will see the e-mail.
Does the system send sensitive information via e-mail?
Another issue with retrieving passwords is how you deliver the password back to the user. For example, when I looked at E*Trade's password retrieval scheme, I was at first quite impressed. You cannot retrieve a password, you can only reset it. The password retrieval page is SSL encrypted, so others cannot sniff the network and see your information. You even have to provide some personal information to initiate a password reset. The flaw with the system is that once you reset the password, it sends you a plain text e-mail with a new, temporary password. E-mail is not secure and is plainly visible on the wire between the user and the Web site.
AOL's ScreenName allows password retrieval without any personal authentication: all you need is a screen name to e-mail a user's password. If you are able to sniff a network, all you have to do is go to the password reminder page, enter the screen name, and then see what password is sent to the user.
Another common practice is to send users a confirmation e-mail containing their username and password, along with the recommendation to save that e-mail for future reference. Not only does this put the passwords at risk by sending them plain text over the wire, but it also encourages users to save these e-mails in their mail client.
Does the system assign temporary passwords?
If your system assigns temporary passwords, you should require either a password change after the first log-in or limit how long users can use temporary passwords. Several years ago, I subscribed to an online book service but later forgot my password. I submitted the password change request but I was required to answer a secret question, which I had not set up. I ended up sending an e-mail to the customer service department. A customer service representative promptly sent me a temporary password. In her e-mail she told me to change the password after logging in, because she gives everyone the same temporary password when she resets passwords. As soon as I logged in, I went to change my password, but couldn't figure out how to do it. Eventually I did change it, but I would guess that many others would quickly give up and just keep the temporary password. This can be avoided by doing two things: don't let customer service reps set passwords and limit the use of temporary passwords.
Does the system use password reminders?
Although they seem useful, password reminders or secret questions can actually weaken a system's security. For instance, when I signed up for an online air miles account with one major airline, it required that I provide a password of at least eight characters, a great practice that would allow a minimum of 218,340,105,584,896 possible passwords. However, it then asked me for a secret question, and gave me two fixed choices: my mother's maiden name or a pet's name.
The interesting thing about this is that there are only about 25,000 common surnames in the United States, which is roughly the number of permutations and combinations afforded by a three-character password. But if a hacker doesn't have time or a script to enter 25,000 names, there is a one in ten chance that someone in the U.S. will have one of the following names: Smith, Johnson, Williams, Jones, Brown, Davis, Miller, Wilson, Moore, Taylor, Anderson, Thomas, Jackson, White, Harris, Martin, Thompson, Garcia, Martinez, Robinson, Clark, Rodriguez, Lewis, Lee, Walker, Hall, Allen, or Young.
The top twenty pet names, according to a dog tag manufacturer, are: Max, Buddy, Molly, Bailey, Maggie, Lucy, Jake, Rocky, Sadie, Lucky, Daisy, Jack, Sam, Shadow, Bear, Buster, Lady, Ginger, Abby, and Toby.
If you do provide fixed secret questions, you should provide at least twenty, but preferably more questions from which to choose. Another option is to let the user select the secret question and provide an answer. While this provides many more options than a fixed set of questions, not all users will use them responsibly. Here are some examples of secret questions I have seen:
What is my name?
What's my e-mail address?
What is my password? (if you knew that, you wouldn't need the secret question would you?)
Another option that I sometimes see is just a simple password hint. This is the absolute worst thing you could do, as users often enter their actual password as the hint. If you really must do something like this, then make sure that the hint does not contain the user's actual password.
Secret questions can be useful but it is important that they not be the equivalent of a password. A secret question should be used to validate users so that you can reset their password, but should not be used to log in to the account.
This concludes the first part of this two-part article discussing some questions to audit the security of Web site authentication. This installment has focused on issues surrounding usernames and passwords. The second part of this article will explore issues surrounding user privacy, session authentication, user security, and cookies.