Secure login systems
Tags: webdevelopment, security.
By lucb1e on 2011-11-20 16:30:45 +0100
What a secure login system should be like:
- The password field must hide the password;
- The login processing script must be called via HTTPS, or if over HTTP the login must be hashed before transmission;
- The password should be hashed via a secure hashing algorithm, I consider sha1 the minimum;
- The hash should be salted;
- The username or another static and user-specific should be included with the salt;
- The hash should be run a lot of times, like 100 or so;
- The hash should NOT be retrieved from the database and then checked, it should be sent to the database and checked there;
- The hashing method used should not be mentioned publicly;
- The database should only accept connections from the webserver, not anyone on the web;
- The login system should only accept a number of invalid login attempts per minute per IP address;
- Passwords should be checked for complexity and against a basic dictionary, when it isn't strong enough the user should receive a warning or error;
- The password should not be e-mailed to the user;
- Pad the resulting salt in the database with something which makes it look like another hashing algo;
- Whether the username is right should not be told, the result is "valid" or "invalid", don't give a potential attacker any hints how far he got;
- Do NOT use a "security question" to reset someone's password. Ever.
- The password field must accept at least 30 characters, although 50 or more is recommended.
With all this, I think we are fairly close to a secure login system. Now the rest of the website...
Of course this can be expanded with a two-factor authentication system and such, but for basic websites this is about the standard. Except maybe #11 it's all easily doable. In any system I build, I consider this good practice rather than something especially secure.
- Obvious, but I've seen websites without it;
- The alternative mentioned is not nearly as safe as HTTPS, but it's a lot more secure than neither;
- Depending on the level of security required, sha-256 or better might be considered. Never combine methods (like: sha(md5(sha512(password)))): security is only as strong as the weakest key in the chain;
- This way an attacker can't generate or use a single rainbow table for all users in the database;
- You can argue that this takes away a lot of server time, but how often do users login or register compared to pageloads? Also it takes nearly no time, this server is very slow and handles 100 sha1 loops with salt in about a millisecond;
- Incase anyone can ever get between the webserver and database-server connection, the correct salt should not be retrieved from the database;
- Security through obscurity measure, but it can't hurt. In fact you may announce you're using a weaker hashing algorithm than you actually are (but be sure to claim something which length fits with what you store);
- On IPs with many users, like a school for example, it's too bad if some weirdos are running a brute force attack against the login, this is the only way to keep it secure. The system administrators should make sure their network is clean and the users behave, you have a service to keep running securely. Although there are also attacks possible with a spoofed source IP, they are much, much harder;
- Because who says their mailserver or inter-mailserver communication is secure?
- Like if you use sha-224, pad it with 4 bytes to make it look like a sha-256 hash. Attackers will attempt to break it with sha-256 if they can't see the login method;
- Security questions to reset your password are the worst invention ever. Even a 13-year-old can hack users this way (I can tell because I was 13 with I did that lol).
- FAR too many websites allow FAR too short passwords. It's ridiculous, when you click the question mark next to the login field at Bol.com it gives you some password recommendations. Pretty much the standard guidelines which are never followed: Minimum of 8 characters, use special characters, use a unique one for every website and every account, and change it often. If you would follow this, and you would want a totally unique yet rememberable password for every website, you will need like 20 characters at the very, very least. Bol.com however only allows 12. I never get this, why in the world do you need any length limit at all? In fact a 5MB password would be fine. Impractical, but I see no problem. The database only stores the hash, doesn't it? ... Guys? It hashes it, right?!
Again about number 15, this is perhaps a fun way to get logins for Microsoft Windows Live accounts:
- Create a website promising some uber-awesome service;
- Require users to sign up, perhaps for a closed beta;
- Require them to set a security question, and make them answer the same question as the service you want to target (for example if Hotmail asks for the color of your first car, make that one of the questions).
Then create some script notifying you whenever someone registered with an @msn, @hotmail or @live e-mail address. Try logging in with the password the user entered to register, this works in about 20-30% of the cases (according to own experience). If that fails, try their security question.
You don't even need to replicate the hotmail website like for phishing attacks. Nobody will report it as a scam website because nobody will know they got hacked via this website.
(No I'm not black-hat, I call this raising awareness. If I was blackhat, I would have used it or sold it, not told the world about it.)