Skip to content

Three sure signs that you are doing something wrong when building a webapp

We all make mistakes, but there are three schoolboy errors I see committed by web developers on a depressingly regular basis which indicate that they don’t really understand what they are doing.  What’s really worrying is the number of major sites that commit these easily avoidable errors.

Not letting me use perfectly valid email addresses

I covered most of this in my previous blog item on validating email addresses in Rails but it’s worth repeating…

If you don’t let me use a ‘+’ in my email address I will hunt you down and beat you to death with a stone engraving of RFC5322

Almost every platform, language, toolkit and framework should come with something that will validate an email address, you’ll probably find it in the respective mail library.

If you are not using an off-the-shelf address validator you are wasting effort building something that will almost certainly be worse.

Unless you know RFC5322 back-to-front, don’t write your own email address validator.  And even then you should only be doing it if a suitable one doesn’t exist on your platform.

Did you know…

  • is a valid email address (yep, domains can be one letter long)
  • !#$%&’*+-/=?^_`{|}~ are all valid characters in the local part (before the @) of an email address
  • that the characters “(),:;<>@[\] can be used in the local part if you want (but with some restrictions)
  • that and are valid domain names?
  • that and are technically different addresses, but most servers will treat them the same (but this is just convention, not a standard).
  • is a valid email address and for most mail servers will be delivered to the same mail box as although that’s also just convention and will depend on the mail server.

If you didn’t know all this then don’t write your own address validator unless you have a pretty good reason. You are almost certainly wasting your time reinventing the wheel.

Sending Passwords to your Users in Plaintext

There are two bloody good reasons why you shouldn’t be sending passwords in plaintext emails:

You have no idea who has access to that email

Between your systems and the user’s brain are a host of email servers, routers and networking gear, not to mention the user’s own computer.  Any one of these could be compromised, be it an insecure email system, the user’s own virus infested PC, or the unencrypted free coffeeshop wifi they are using.

Your user probably uses that password on every other service they sign up for

It’s a sad fact that most users are bad at picking passwords, and will reuse one for everything they sign up for.  If your service exposes their password to the world, you are not just compromising the security of their account on your service, but also many other services.

You shouldn’t even know the user’s password

If you are doing things properly, you should be storing the password as a hash using an algorithm like SHA2, not in plain text. If you don’t know what a hash is, put your editor down, and get googling.

By storing passwords in hashes you limit the damage done to your customers if your user database gets hacked.  If your plaintext, or badly hashed (MD5 is basically useless now), database of usernames, email address and passwords get’s exposed, chances are you’ve just handed out the keys to your users’ Facebook, Twitter, email and god-knows what other accounts.  I’ll bet a significant percentage of them are exactly the same.

If the PlayStation network can be hacked then do you really think your database is that secure?

Limiting the Length of Passwords

When a website limits the length of password I can use I start to get very worried about the security of the site. The length of a password is the single most important factor in how secure a password is.  If you limit the length of the passwords your users can use, you are actively limiting how secure your system is.

Obligatory XKCD comic complete with explanation

Lets get this straight: there are few (if any) good technical reasons for restricting the length of a password, except at the extreme upper limits, such as the maximum size of an HTTP POST parameter on your system

“But I need to limit the space it takes up in the database/I’m storing it in a fixed width column…”

Don’t forget, you should be hashing your passwords…

One of the key features of a hash algorithm is that the output is always the same length. A SHA-512 hash is always 512 bits long (64 8-bit ASCII characters), irrespective of how long the input data is.  That means that what you store in the database is always the same size, whether the user has a three letter password or a three thousand letter password.

“It would take too long to hash those long passwords…”

Aside from “Premature optimisation is the root of all evil”,  the two golden rules of performance optimisation are:

  1. You don’t have a performance problem until you can show me a graph of it.
  2. You don’t know what’s causing the problem until you can show me the output from a profiler.

As an example, SHA-512 can be computed at a rate of tens of millions of bytes per second on a fairly normal machine.  Stopping your users from using thirty or forty character passwords is not going to make much difference to how long hashing them takes.

Don’t forget, that hash will only be computed once per login.  Once you’ve authenticated the user you shouldn’t have to touch that password again.

If you have a busy enough service that the computing resources used to hash passwords is actually a major problem for you, then you’re big enough to throw more hardware at the problem.

But the Big Question is: Why are your doing all this work in the first place?

Seriously. Don’t you have better things to do with your time?

Pretty much every language or framework worth using has some kind of authentication system available.  If you use Rails then the gold standard at the moment is Devise, I’m sure there are good ones for Code Igniter, Groovy and the likes.

Why do more work than you have to, and risk screwing it up in the process when there are well used, heavily tested, and battle-hardened alternatives out there that you can just use and that will do all these things right first time?  With all that time you wasted writing an auth module you could have finished the important stuff in your application.

I’ll just leave you with this Stack Overflow question, in which the second answerer (is that really a word?), in trying to demonstrate that “An authentication library really isn’t that hard to write” disproves his point by having a massive SQL injection hole in his.