Skip to main content
gamedev.net
🔒 Locked

[web] [SQL] Where-Statement problem

Started by Jockel Jul 1, 2006 at 4:54 PM 4 replies 1k views
Original Post
Jockel
Jockel
I've got a little understanding problem with a basic SQL-Statement. I have a table where the field 'Id' is an unsigned integer which is also the primary key. Now I have the following query: SELECT * FROM table WHERE Id='foo' Due to the fact, that I compare 'Id' with a string I expect an empty result set. But the result set contains the one dataset where the Id equals 0. If there is no such dataset (with Id=0) the returned result set is empty. If I use instead the following statement, the behaviour is like I expect it: SELECT * FROM table WHERE Id LIKE 'foo' Can someone explain me, why the first statement returns a result set, even though Id is defined as an integer? Btw.: I've tested this on a MySQL-Server 4.0.18 and I couldn't find an explanation in the documentation...
Kylotan
Kylotan
Is it really a problem? After all, you wouldn't really want to query an unsigned int column with a string parameter, right?

I seem to recall reading somewhere that MySQL - or perhaps, older versions of it - are quite lax in their type-checking, and what you're seeing here is probably a side-effect of that. It probably sees that you are comparing with an integer, makes an attempt to convert the string to an integer - yielding zero in this case - and then uses that to perform the match. Try using "two" or "2" as in the string and see if it returns the row with id=2, for example.
Jockel
Jockel
Hm, I'm not sure, if it's really a problem... I asked this because I have this SQL statement in a web application. The id is passed as a request parameter. To prevent SQL injections I use a prepared statement. If a user is now manipulating the id, e.g. trying a SQL injection attack, he will not succeed but will see the dataset where id equals 0. The page I encountered this problem does not contain any sensitive data at the moment but I'm still not feeling comfortable that my web application shows some data, which the user should not see.

I'm thinking about two possible solutions:
1) Inserting a dataset with id=0 which contains no more data.
2) Using the LIKE operator.

Is there any draftback using the LIKE operator? Or does anyone can think of a better solution?

@Kylotan:
I've tried to used "two" but this is not returning the dataset with id=2. If I use "2" or "2foo" the dataset with id=2 is returned. So characters behind the numbers a truncated and I receive the dataset where id equals the requested number. Are characters in front of the numbers I get the dataset with id=0.
Kylotan
Kylotan
The value is probably getting passed through C's atoi() function. I think you really need to check the value before you pass it to MySQL. A prepared statement can protect you from an injection attack but it can't protect you when the SQL statement is in the expected form. If there are values of id that you don't want a given user to be able to submit, then you absolutely must check them yourself between the browser and the database.
Raz Malone
Raz Malone
One thing to do is just through something in there to check what the value is being passed and if it's not a valid number then it'll just through up an error message instead of even proccessing the sql satement.
Jockel
Jockel
Thanks for the replies. Seems like I just have to change a 'little' bit of my code... Really, I don't understand this behaviour. It makes no sense to me. Anyway, learned again something. Thanks for the help.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.