Locks and Keys - Code Audits #8

In software development, it is common to have users authenticate using usernames and passwords. In order to handle the authentication process, we must store this information in some way. Obvious, passwords should never be stored in clear text. Toward that end, when we store them, we encrypt, hash, salt, etc. to keep them safe.

While these steps cannot protect against all forms of attack, they’re a good base of protection to have in place. We don’t want to just give this information away to anyone who wants it. Yes, some people could take the non-clear-text passwords and obtain the original password from it, but we’ve certainly set the barrier higher.

Security is all about setting more and larger hurdles in place for people to jump over. The only secure information is information that doesn’t exist, and that becomes inherently insecure as soon as it does exist. If information is accessible to someone, it means that it’s possible for someone else to access that information also.

We just try to make things more difficult and limit that damage. Or at least some of us do.

I’ve made plenty of my own mistakes in the past. Some of the applications I wrote in college have security holes, which seem glaring to me now, but I’d not even noticed at the time I wrote the code. I’m sure that most people reading this would say the same thing about their own code.

The Bad

One of the systems I had the pleasure of seeing the code for, at its core, was a customer portal. It even had its own custom ecommerce solution. (These details while talking about security issues will have some of you facepalming already.)

The developers knew that they needed to encrypt the passwords, so they wrote some sql, dbo.encrypt, to encrypt passwords before storing them in the database. Insert a password and out comes a jumbled mess that no one could read.

Users will often forget passwords, and will need some way of recovering from this situation. I recommend resetting passwords when this happens. This application took a different approach.

Also stored in the database was some other useful sql, dbo.decrypt, which would take any of the encrypted passwords and decrypt them. Well that’s obviously a security issue, but the worst thing about this isn’t just that it’s reversible. It’s that this is also in the database. That means that we have the lock and the key together. If someone gets read-only database access, but not access to the application’s source code, they still have everything.

It’s like have a lock and keeping the key inside the lock for convenience. I wouldn’t want to have to call a locksmith if I ever lost the key, so I just keep it here. It makes opening the lock faster too!

The Better

Don’t allow reversing of stored passwords. Use 1-way only when dealing with passwords. This way brute force techniques are required to figure out a password.

If the system can reverse the password back to the original, anyone who has obtained access to the system can retrieve all of the passwords.

This isn’t a new idea. You’re not the first developer to set up authentication in an application. There are plenty of existing authentication systems out there. Don’t reinvent the wheel if you don’t have to. Some systems are safer than others. Ask around. Talk with security experts (I am not one of them) about these if your application requires really high hurdles.

More Code Audit Nuggets

Keep watching for more interesting nuggets of stuff that I’ve seen in codebases.