Jump to content

ctype_digit()


chokk

Recommended Posts

Hey,I'm using ctype_digit() to filter input to a variable called $id. The value of the variable is passed into an SQL statement. Is it possible to inject SQL into the $id variable, even though it is being filtered by a ctype function?Thanks

Link to comment
Share on other sites

ctype_digit() doesn't filter... it checks. It's up to you to actually filter it. ctype_digit($id) will return true or false, based on whether the value consists of only digits, but $id remains unchanged.If you do for example:

ctype_digit($id);$sql = "SELECT * FROM users WHERE id=$id";mysql_query($sql);//rest of the code

you're essentially doing nothing.If you're doing

if (ctype_digit($id)) {$sql = "SELECT * FROM users WHERE id=$id";mysql_query($sql);//rest of the code}else {//What to do if $id is not a digit}

That's another story... that's safe, but the value is not "filtered" or "sanitized". To do that would imply to actually turn it into a valid value in some way, the easiest of which is a plain type cast, like:

$id = (int) $id;$sql = "SELECT * FROM users WHERE id=$id";mysql_query($sql);//rest of the code

In this fashion, there's no way for $id to ever not be an integer of some sort. It may not be an integer you expect (e.g. it could be a negative number, which could cause problems if your DB field was an unsigned integer), but it will be an integer non the less.

Link to comment
Share on other sites

Thanks for your reply, boen! A big help as usual! : o )I'm using the $id variable in the URL to display content on my website. I was wondering if anyone could inject something there, because I haven't escaped it..Example:

if(ctype_digit($_GET['id'])){$id = $_GET['id'];}

When I have the id of the page to display I load the body from the database corresponding to that id..What I understood from your post, I'm safe using this technique... (right?) :)Again, thanks for your reply!

Link to comment
Share on other sites

Yes, but only if you also define what happens in case the value is not valid.That's essentially what escaping/sanitizing/filtering is - make any invalid value a valid one, or use it as is if it's already a valid value. It's just that you're doing it "manually" here.So let's say that by default, you use 1 as an ID in case the number is not valid, i.e.

if(ctype_digit($_GET['id'])){$id = $_GET['id'];}else {$id = 1;}

That's one way... another way is to switch to a new thing altogether, such as performing a separate query in which the variable doesn't exist, like:

if(ctype_digit($_GET['id'])){$id = $_GET['id'];mysql_query("SELECT * FROM posts WHERE id = $id");}else {mysql_query("SELECT * FROM posts");}

That's another just as safe way... it all depends on what you want, but to be safe, you must define SOMETHING that happens on error. Otherwise, an invalid value could cause issues other than SQL injection, such as error message display (which could aid attackers into exploiting other parts of your code).Personally, I prefer to do the type casting thing above, plus turning negative values to 0 (if the targeted field is an unsigned integer), because that way, you don't have to define anything in case the value is invalid - it always is by definition.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...