Page 1 of 1

Validating and Sanitizing PHP DB INPUT HELP PLEASE

Posted: Wed Sep 08, 2010 7:21 am
by Jenny Dithe
Hi,

I would be incredibly grateful for any help as I have taken this as far as I am able and am now in a position where I am just confused by all the different methods I have seen. I have my HTML form and I am sending my information to the insertinto form and am trying to validate, sanitize and prevent injections before the data is put into the database. At the moment it is a mess and not working, all I get is the first response, "Please enter a firstname" even if I have entered a firstname.

Please could someone help me with:
1. What am I doing wrong (I think my code is becoming worse each time I try to solve the problem)?
2. Am I doing everything to protect my code and database, I hear people mentioning MD5 but have no idea what it is. Should I being this or anything else in addition to what is involved?

Code: Select all

<html>
<head>

</head>
<body>
<?php
$filters=array
	(
	"fname"=>array
		(
		"filter"=>FILTER_SANITIZE_STRING
		),
	"lname"=>array
		(
		"filter"=>FILTER_SANITIZE_STRING
		),
	"email"=>FILTER_VALIDATE_EMAIL,
		
	"cemail"=>FILTER_VALIDATE_EMAIL,
			
	"pword"=>array
		(
		"filter"=>FILTER_SANITIZE_INT,
		"options"=>array
			(
			"min_range"=>1,
			"max_range"=>9,
			"strlen"=>12
			)
		),
	"cpword"=>array
		(
		"filter"=>FILTER_SANITIZE_INT,
		"options"=>array
			(
			"min_range"=>1,
			"max_range"=>9,
			"strlen"=>12
			)
		),
	"dobyear"=>array
		(
		"filter"=>FILTER_SANITIZE_INT,
		"options"=>array
			(
			"min_range"=>1992
			)
		),
	"natcountry"=>array
		(
		"filter"=>FILTER_SANITIZE_STRING
		),
	"rcountry"=>array
		(
		"filter"=>FILTER_SANITIZE_STRING
		),
	"postcode"=>array
		(
		"filter"=>FILTER_SANITIZE_STRING
		),
	"other"=>array
		(
		"filter"=>FILTER_SANITIZE_STRING
		),
	);


	$result = filter_input_array(INPUT_GET, $filters);


	if (!$result["fname"])
		{
		echo("Please enter your first name.<br />");return false;
		}
	elseif (!$result["lname"])
		{
		echo("Please enter your last name.<br />"); return false;
		}
	elseif (!$result["email"])
		{
		echo("Email address is not valid.<br />"); return false;
		}
	elseif (!$result["cemail"])
		{
		echo("Your email addresses do not match.<br />"); return false;
		}
	elseif (!$result["pword"])
		{
		echo("Please ensure your password includes a number between 0-9.<br />"); return false;
		}
	elseif (!$result["cpword"])
		{
		echo("Please ensure your password includes a number between 0-9.<br />"); return false;
		}
	elseif (!$result["dobyear"])
		{
		echo("Users must be over 18 years old<br />"); return false;
		}	
	elseif (!$result["natcountry"])
		{
		echo("Please select your nationality.<br />"); return false;
		}
	elseif (!$result["rcountry"])
		{
		echo("Please select your country of residence.<br />"); return false;
		}
	elseif (!$result["postcode"])
		{
		echo("Please enter your postcode.<br />"); return false;
		}
	elseif (!$result["industry"])
		{
		echo("Please select your industry.<br />"); return false;
		}
	else
		{
		return true;
		}
		

	if ($fname=='enter firstname')
		{
		echo("Please enter your first name.<br />");return false;
		}
	elseif ($lname=='enter surname')
		{
		echo("Please enter your last name.<br />"); return false;
		}
	elseif ($email=='enter email address')
		{
		echo("Email address is not valid.<br />"); return false;
		}
	elseif ($cemail=='confirm email address' OR $cemail=='!email')
		{
		echo("Your email addresses do not match.<br />"); return false;
		}
	elseif ($pword='password')
		{
		echo("Please ensure your password includes a number between 0-9.<br />"); return false;
		}
	elseif ($cpword=='password' OR $cpword=='!pword')
		{
		echo("Please ensure your password includes a number between 0-9.<br />"); return false;
		}
	elseif ($DOByear=='please select')
		{
		echo("Users must be over 18 years old<br />"); return false;
		}	
	elseif ($natcountry=='please select')
		{
		echo("Please select your nationality.<br />"); return false;
		}
	elseif ($rcountry=='please select')
		{
		echo("Please select your country of residence.<br />"); return false;
		}
	elseif ($postcode=='enter postcode')
		{
		echo("Please enter your postcode.<br />"); return false;
		}
	elseif ($industry=='please select')
		{
		echo("Please select your industry.<br />"); return false;
		}
	else
		{
		return true;
		}

function check_input($value)
{
if (get_magic_quotes_gpc())
	{
	$value=stripslashes($value);
	}
	
if (!is_numeric($value))
	{
	$value = "'" . mysql_real_escape_string($value) . "'";
	}
return $value;
}

	$con = mysql_connect("localhost","user","password");
	if (!$con)
		{
		die('Could not connect: ' . mysql_error());
		}

	mysql_select_db("my_db", $con);

	$sql="INSERT INTO members(fname, lname, email, cemail, pword, cpword, sex, DOBMonth, DOBDay, DOBYear, natcountry, rcountry, postcode, industry, other, date)
		VALUES
	('$_POST[fname]','$_POST[lname]','$_POST[email]','$_POST[cemail]','$_POST[pword]','$_POST[cpword]','$_POST[sex]','$_POST[DoBMonth]','$_POST[DOBDay]','$_POST[DoBYear]','$_POST[sex]','$_POST[ncountry]','$_POST[postcode]','$_POST[industry]','$_POST[other]','$_GET[CURDATE]')";

	if (!mysql_query($sql,$con))
		{
		die('Error: ' . mysql_error);
		}

	mysql_close($con);

?>

</body>
</html>

Re: Validating and Sanitizing PHP DB INPUT HELP PLEASE

Posted: Wed Sep 08, 2010 3:12 pm
by califdon
I haven't even tried to look at your entire script, but I simply don't understand what you are trying do with that $filters array, nor all those if - elseif's. The best I can do is try to help you clear your mind about what should be very simple operations:

The place you need to protect data entered into a web form is when you extract them from the $_POST array. So just use either the PHP function filter_var() (ref. http://www.w3schools.com/PHP/func_filter_var.asp) or (my preference) the PHP function mysql_real_escape_string() (ref. http://php.net/manual/en/function.mysql ... string.php) if you have already connected to a mysql server, for each variable, like this:

Code: Select all

$name = filter_var($_POST['name']);
//  or
$name = mysql_real_escape_string($_POST['name']);
I don't understand why you are creating these arrays.

MD5 is a checksum that is often used to store the checksum for a password, rather than storing the password itself. Current practice is to use SHA instead of MD5, but both are widely used for this purpose. You can compare the checksum of what the user entered against the stored checksum to provide validation, but the password itself is NOT stored anywhere, which is why you have to change your password if you forget it, because even the system administrator has no way to know what your password was.

Re: Validating and Sanitizing PHP DB INPUT HELP PLEASE

Posted: Thu Sep 09, 2010 3:21 am
by Jenny Dithe
Thank you so much.

That makes life significantly simpler. Does this adequately protect my databases if I don't have any other security measures?

I looked at the guidelines. Can I do the below to check all fields or do I need to write each one individually?

Also I am getting mysql Error when I go to my page? Is there anything clearly sticking out as wrong?

Code: Select all

<html>
<head>

</head>
<body>
<?php
function check_input($value)
{
if (get_magic_quotes_gpc())
	{
	$value=stripslashes($value);
	}
	
if (!is_numeric($value))
	{
	$value = "'" . mysql_real_escape_string($value) . "'";
	}
return $value;
}

	$con = mysql_connect("localhost","user","password");
	if (!$con)
		{
		die('Could not connect: ' . mysql_error());
		}

	mysql_select_db("my_db", $con);

	$sql="INSERT INTO table(fname, lname, email, cemail, pword, cpword, sex, DOBMonth, DOBDay, DOBYear, natcountry, rcountry, postcode, industry, other, date)
		VALUES
	('$_POST[fname]','$_POST[lname]','$_POST[email]','$_POST[cemail]','$_POST[pword]','$_POST[cpword]','$_POST[sex]','$_POST[DoBMonth]','$_POST[DOBDay]','$_POST[DoBYear]','$_POST[sex]','$_POST[ncountry]','$_POST[postcode]','$_POST[industry]','$_POST[other]','$_GET[CURDATE]')";

	if (!mysql_query($sql,$con))
		{
		die('Error: ' . mysql_error);
		}

	mysql_close($con);

?>

</body>
</html>

Re: Validating and Sanitizing PHP DB INPUT HELP PLEASE

Posted: Thu Sep 09, 2010 11:01 am
by califdon
No, somehow you're missing the point. You have to use something like mysql_real_escape_string() on EVERY VALUE. Look at your code: you are directly feeding the unescaped $_POST values into your SQL statement. That's the very thing that is dangerous! Make variables for each one that sanitize them, THEN use the variables in your SQL. Like this:

Code: Select all

...
$fname = mysql_real_escape_string($_POST['fname'];
$lname = mysql_real_escape_string($_POST['lname'];
...
...
$sql = "INSERT INTO table (fname, lname, ...
...
VALUES ($fname, $lname, ...
I'm not a security expert and I would hesitate to say that there are not other protections that you could use, but the above is a pretty standard way to defeat the most common "sql injection" hacks.

You have defined a function called "check_input", but you haven't used it anywhere, so it is useless. To use it, you would have to call the function for each of your variables. Then you would have a problem with the fact that the function adds quotes around non-numeric values, then you are inserting quotes around them when you build your SQL statement, resulting in 2 quotes, which would produce a syntax error. I would just eliminate that function.

Re: Validating and Sanitizing PHP DB INPUT HELP PLEASE

Posted: Thu Sep 09, 2010 11:05 am
by califdon
No, somehow you're missing the point. You have to use something like mysql_real_escape_string() on EVERY VALUE. Look at your code: you are directly feeding the unescaped $_POST values into your SQL statement. That's the very thing that is dangerous! Make variables for each one that sanitize them, THEN use the variables in your SQL. Like this:

Code: Select all

...
$fname = mysql_real_escape_string($_POST['fname']);
$lname = mysql_real_escape_string($_POST['lname']);
...
...
$sql = "INSERT INTO table (fname, lname, ...
...
VALUES ('$fname', '$lname', ...
I'm not a security expert and I would hesitate to say that there are not other protections that you could use, but the above is a pretty standard way to defeat the most common "sql injection" hacks.

You have defined a function called "check_input", but you haven't used it anywhere, so it is useless. To use it, you would have to call the function for each of your variables. Then you would have a problem with the fact that the function adds quotes around non-numeric values, then you are inserting quotes around them when you build your SQL statement, resulting in 2 quotes, which would produce a syntax error. I would just eliminate that function.

When you are posting PHP code here, please use the "PHP Code" button at the top of the editing screen to make your posts more readable. I have fixed both of your posts.