Here is a database query that has a potentially huge problem:
select * from users where username = '$username' and password = '$password'
If you’re not a programmer, bear with me, I’m sure you can still follow the problem here. In the line above, $username contains the value the user gave for their username, and $password contains the value given for their password. Let’s say my username is “kip” and my password is “12345”. That gives us:
select * from users where username = 'kip' and password = '12345'
So far so good, a database can execute that just fine. But what if my password is “My dog’s name is spot”? That gives us this:
select * from users where username = 'kip' and password = 'My dog's name is spot'
See the problem? The database will think the password is just “My dog”, since there is a single-quote in the password. It will additionally not know how to handle the rest of the statement and probably return an error, preventing the user from ever logging in.
Nothing I’ve said here of this should be news to a programmer. In introductory programming courses, students are often asked to write a program where the user is asked for input (let’s say, a number from 1-10), and the program must not fail if the user enters something entirely different (let’s say, “judicious”). What is happening in my example is in no way fundamentally different.
If you’re thinking to yourself, “Hey Kip... you’re not writing this post because you just figured this out.. are you?”, rest assured that I am not. I am writing this because (a) I like to pretend that my blog has more than a dozen readers; and (b) because I have seen several sites discussing this type of bug lately. The implication is that many programmers—presumably the paid, professional types (not just amateurs)—would put user input inside single-quotes without entertaining the possibility that the user might enter text with single quotes in it. It seems like one of those things that you shouldn’t need to be taught—you should logically know to validate user input, even if you have never received formal training in programming.
Thus far, I haven’t even talked about the security hole caused by this code: someone could intentionally use a single-quote in their password to exploit this bad code. For just one of many examples, giving a password of “‘ or ‘abc’ = ‘abc” will let you into any existing user’s account (this is called SQL Injection). I can understand why a programmer might not see that security hole immediately. But the security hole is just an abuse of a bug that a logical human being should have seen in the first place.
</soapbox>
<--- THIS IS NOT LONDON BRIDGE!
November 13, 7:48 pm
If you’re a serious developer, you might consider moving away from using pure SQL and embracing an ORM like Hibernate.
November 14, 8:13 am
PHP5 added this really nice PHP Data Objects (PDO) extension that is ORM-like so you don’t have to mess with any of the SQL commands anymore. It’s nice to not have to write your own database abstraction layer now.