What Your Users Don’t Know (Part 1)


(This is part 1 of a series on web security; see part 2.)
What’s wrong with this code?
Any jokester who says “it looks fine to me” will be sent to the spice mines of Kessel. But I think for observant readers, a couple of critical security errors will practically jump off the screen:

  • User inputs are being concatenated directly into a SQL query string, risking a SQL injection attack.
  • Passwords are stored in plaintext, exposing users to further harm in the event the database is accessed.

In the Real World

If you keep up with the news, you may have seen that no less an internet giant than Yahoo may have been guilty of both of the above mistakes, leading to a breach of 435K user credentials. This is a disaster for any company that safeguards private user data.
You can’t depend on users to protect themselves; somewhere out in the world today is a person who set up the same password on a Justin Bieber mailing list website and also their online banking. So if even a fluffy, non-important website drops the ball, users may see their bank accounts emptied. That’s probably an extreme worst case, though there is a whole range of other mischief you don’t want to enable either. The point is, your users trust you, and they don’t know what you are doing with their data. Be worthy of their trust.

Get In the Mindset

A technique I find helpful for programmers is to temporarily put down their shining knight helmet and try on a black hat for size. Put yourself in a creative trouble-maker frame of mind. Ask the question: how could somebody compromise my website and harm my users or my organization?

SQL Injection

In the case of the code snippet at the top of this article, it is trivially easy for a hacker to enter a user name or password that will disrupt the query. By placing complex SQL expressions (perhaps cleverly including SQL comments) in the user name and password inputs, you can easily delete or insert records. What would totally frustrate your hacking attempts, though, is if the programmer used their framework’s feature for formal query value parameters (see for C#, Python, etc). And that, of course, is the correct answer here. Never concatenate user inputs into SQL strings. It’s even a bad idea to write your own sanitizing functions, because you’ll probably get a detail wrong, even if you’re a smart person. Just use the framework, all the time, or else use a mainstream ORM that hides the query string safely out of your code’s sight.

Plaintext Passwords

Salt and Pepper by Jon Sullivan

Photo by Jon Sullivan

The other major problem is the use of plaintext password storage. That’s obviously a really bad thing if the database is accessed, and many programmers are aware that if you just do a one-way hash of the password, it’s more secure. You do lose the ability to remind the user of their password, but it’s usually OK, because they can just create a new one when needed via an email challenge/response. But even hashing itself doesn’t cut it. If you are not salting your password hashes, your users are exposed to unacceptable risk.

I’ll take a closer look at how to salt passwords in a future post. It really sounds more difficult than it is. So to summarize: do some reading, and also occasionally just put yourself in a black hat frame of mind, and you can work out how to close common loopholes.

+ more

Accurate Timing

Accurate Timing

In many tasks we need to do something at given intervals of time. The most obvious ways may not give you the best results. Time? Meh. The most basic tasks that don't have what you might call CPU-scale time requirements can be handled with the usual language and...

read more