Jump to content


Best protection agaisnt MySQL Injection Attacks?


6 replies to this topic

#1 Forgotten

    Young Padawan

  • Members
  • Pip
  • 63 posts

Posted 18 February 2006 - 07:33 PM

Whats the safest way to protect yourself from mysql injections? I currently use:

function cleanAll () {

	foreach($_POST as $key => $val) { $_GET[$key] = stripslashes(strip_tags(htmlspecialchars($val, ENT_QUOTES))); $$key = $val; }
	foreach($_GET as $key => $val) { $_GET[$key] = stripslashes(strip_tags(htmlspecialchars($val, ENT_QUOTES))); $$key = $val; }
}

Then call the function on every page with a login. But is this better?

function quote_smart($value)
{
	// Stripslashes
	if (get_magic_quotes_gpc()) {
		$value = stripslashes($value);
	}
	// Quote if not integer
	if (!is_numeric($value)) {
		$value = "'" . mysql_real_escape_string($value) . "'";
	}
	return $value;
}

Or do both suck and I need something better? If so, can you post one?

Thanks!

#2 Lang

    Young Padawan

  • Members
  • Pip
  • 198 posts
  • Gender:Male
  • Location:Ontario, Canada

Posted 18 February 2006 - 11:03 PM

Ahhh, SQL Injection. With every great thing like MySQL there's always bad things.

Anyways, what I do to stop with SQL injection from user input is use a javascript function on SOME fields to disallow certain characters like !@# ect ect. But on those fields you don't want to I use htmlspecialchars(); and others. One thing though - if you're going to pass variables through the URL always - ALWAYS make it so that they have to be a number. Then if someone tries to edit one and it's not a number you can have something to control that. You can't use Injection on a site that only allows numbers in the URL.

<?
if (isset($_GET['var'])){
	if (is_numeric($_GET['var'])){
		 $var = $_GET['var'];
   }else{
	   die('Not a number');
   }
}
?>

See where i'm going with this? Anyways to sum it all up htmlspecialchars() and stripslashes() are good. But be careful about what you pass through the URL. And putting a little javascript function in to disallow some characters on some fields wouldn't hurt either.

Edited by Lang, 18 February 2006 - 11:05 PM.


#3 rc69

    PHP Master PD

  • P2L Staff
  • PipPipPipPip
  • 3,827 posts
  • Gender:Male
  • Location:Here
  • Interests:Web Development

Posted 19 February 2006 - 12:16 PM

Personally, i think you only need mysql_real_escape_string() to prevent SQL injection, but as computers have proven time and time again, nothing is fool-proof. strip_tags() and htmlspecialchars() are used to prevent JS or HTML injection into your template from user input.
And as long as you double check everything, the url doesn't have to be just numbers. If you think about it, changing $_GET values i the url is no different then simply typing them into a form and having the $_POST values do their work (rule of thumb, NEVER trust user input, GET, POST, or other-wise indifferent).

Also, you should note the fact that the JS "prevent special characters" is pointless. You can simply open your browser options and turn JS off, so it would be best to use str_replace() on the server side (that way the user can't just disable your security in a few clicks).

Edited by rc69, 19 February 2006 - 12:17 PM.


#4 Forgotten

    Young Padawan

  • Members
  • Pip
  • 63 posts

Posted 19 February 2006 - 04:04 PM

so the best would be only allowing: A-Z a-z 0-9 _ - and space so I dont even need to clean anything since no special characters can be used.

What do you think?

[EDIT] ahh just read rc69's post. What Im using right now seems to be fine (from my point of view), what do you rate it? Im a bit lost now... And the one Im using at the moment has an error when deleting a row from a db using checkboxes.

Quote

Warning: htmlspecialchars() expects parameter 1 to be string, array given in /home/adminal/public_html/templation/design/functions/functions.php on line 193

How can a fix that?

Edited by Forgotten, 19 February 2006 - 04:08 PM.


#5 veridicus

    Young Padawan

  • Members
  • Pip
  • 5 posts

Posted 20 February 2006 - 12:10 PM

1 - ALWAYS validate input on the server side.

2 - Recent versions of mysql are built to not allow execution of multiple sql calls in one statement through the API.

3 - Pass every string through mysql_real_escape_string().

That should cover you 99% of the time. (Would be 100, but can't trust anything completely.)

#6 rc69

    PHP Master PD

  • P2L Staff
  • PipPipPipPip
  • 3,827 posts
  • Gender:Male
  • Location:Here
  • Interests:Web Development

Posted 20 February 2006 - 07:26 PM

http://www.php.net/m...guage.types.php
What ever variable you're passing to htmlspecialchars needs to be a string, not an array.

Also, i just noticed, in your cleanAll() function, you clean $_GET twice. Once using the $_POST values, and again using the cleaned $_POST values.

#7 HaloprO

    Requires Armed Escort

  • Members
  • PipPip
  • 310 posts
  • Gender:Male
  • Location:California, USA

Posted 22 March 2006 - 04:07 AM

Old post, but I was bored..
If you wanted to clean the whole $_GET thing, you can run a loop
<?php
foreach ($_GET as $key => $value) {
	$_GET[$key] = some_clean_function($value);
}
?>
This is not tested :)





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users