Web site security is a very important issue to me. Every application, every information resource, must be built strong enough to put in the Internet, to reliably deliver information to those allowed access, and prevent delivery to those who are not. I find it frustrating sometimes dealing with the “security experts” in IT who operate based more on superstition and urban legends than on solid principles. Part 1 lays down the requirements for a secure web application. Today’s post is prompted by my meeting with such a security expert.
The applications that I design usually have two ways to authenticate yourself (log-in) to the system: OpenID and a combination of email address & password.
OpenID should be the preferred way for people to log in, but it requires an extra conceptual understand which adds to a person’s already crowded day. I remain hopeful that one day OpenID will become common enough that people use them, but until that time I will not expect the average business user to take this option.
Most people prefer to use their email address, and associate a password with that. The application does the normal dance of sending an email message with a token in it. Clicking on a link in that email proves that the person actually owns the email address, and allows the user to create a password. Very simple and secure.
The theory behind a username and a password is clear to everyone: you have a username which is an ID which others might know, and a password which is a secret that nobody else knows . By entering both, you prove to the system that you are the person who knows the secret. Clearly one has to guard the secrecy of password to guard your account from access by others.
This depends upon people choosing a “strong” password. I won’t discuss here what makes a good password, because it quite simply is something that would be hard for someone else to guess. A hacker can only test a password by attempt to login with a guessed value, and see whether it works.
The number of guesses a hacker can make can be limited by system. On my system, if a password login fails, I always delay the failure message by 10 seconds. This means that a casual hacker is limited to less than 9000 attempts a day, while a user that typed a password wrong is inconvenienced for only 10 seconds. As the number of failures increase, the wait time increases as well. After 6 failures, the system locks the account for a few minutes. Using this technique, you can limit the number of guesses that a hacker might make to a few thousand guesses a day, while a user who makes a few mistakes now and then are not inconvenienced at all. A password then needs to be strong enough to be unlikely to guess within a few hundred thousand attempts.
Single words are not strong enough because there simply are not enough words (~80,000). However it is easy to add a few characters and make it hard to guess. Assume you have 100 characters to choose from (given upper and lowercase letters, numbers, and various punctuation and special chatacters) a password with 5 entirely random characters will take ~10^10 guesses which will take thousands of years to guess. A password with 5 entirely random characters would be secure enough.
People are not very good at picking random numbers. We tend to choose characters that fit patterns, and hackers use those patterns to cut down on the number of guesses. We can compensate for this by requiring more characters. two or three words with a couple punctuation thrown into random places within the words is enough to make the password strong enough to take thousands of years to guess on a brute force attack.
The point here is that it is not hard to create a password that is strong enough to keep the system safe. The longer the password, the safer the system, right? Would a system that required the user to type 1000 random characters to log in be safer than one that required 6 random characters? Probably not, because a user with a 1000 character password would have to write that down, and carry it on a piece of paper. Whenever a password is written down, there is a possibility it could be read / copied by someone else. Such a piece of paper would usually be kept near the equipment used to log in, and so easy to find.
The best way to keep a password safe, is to allow the user to make a password that is strong enough to avoid guessing, and still easy enough that the user can keep it in memory. A couple words with some random characters thrown in between 10 and 16 characters long fits the bill: it prevents a brute force attempt to guess, and it still can be easily remembered.
A smart system requires only
- a password – strong enough to withstand 100,000 guesses.
- an email address to identify the user associated with the password. The email does not need to be secret, because the password by itself is strong enough.
- a display name for each user. The display name should be used on the site to identify the user to others, but has nothing to do with logging in.
- For technical reasons, the system usually needs an internal unique id in order to make unambiguous references to the user. This is not required at login time, and in fact there is no reason the user should have to be aware of this at all.
This is necessary and sufficient for a site to have completely secure authentication. Security can be raised by requiring longer passwords, or incorporating the use of a device that gives the user a new password every minute. But the pattern does not change – you log in with a non-secure username, and a secret password.
Part 2 discusses a security expert who felt that user names needed to be secret as well. Part 3 discusses how some people mistake the login id with a display name. Part 4 talks about other ways that complicate usage, and in so doing add nothing to the security.