I've started to get serious about php security after reading Chris Schiflett's "Essential PHP Security" from O'Reilly. I never realized there was so much to consider. His advice seems to differ some from other sources I have read, so I have combined a couple things.
So my question: Is this a good start to prevention of sql injection? The culprit is a form that allows the user to enter an address, at which point a temporary table is constructed from 4 other MySQL tables.
(I realize it's no longer proper to use mysql_error() or to display too much information to the user, where such errors are concerned. This is for development purposes. I plan to implement a basic sql error function and log the errors for maintenance purposes in place of mysql_error.)
$address = $_REQUEST['address'];
if(get_magic_quotes_gpc()) {
$address = stripslashes($address);
}
$clean = array();
$mysql = array();
$clean['address'] = $address;
$mysql['address'] = mysql_real_escape_string($clean['address']);
// check to be sure field is not empty
if (!Validate::isNotEmpty($mysql['address'])) {
$errmsg = "<li class=\"error\">Please enter an address.<br />";
}
// check to be sure field contains only digits, alpha, spaces, or specified punctuation: ,.'
$regexp = '#^[a-z0-9,\.\'\s]+$#i';
if (!preg_match($regexp, $mysql['address'])) {
$errmsg = "<li class=\"error\">Invalid characters; you'll get better results if you leave out punctuation.<br />";
}
if ($errmsg) {
echo "<br clear=\"all\" />";
echo "<ul>".$errmsg."</ul>";
addressForm();
echo "<br />";
} else {
//stuff here...then temp table constructed
$database->query("DROP TEMPORARY TABLE IF EXISTS AddressSearch;") or die(mysql_error());
$database->query("CREATE TEMPORARY TABLE AddressSearch (
ListNum INT(10) UNSIGNED NOT NULL DEFAULT 0,
AddressNum VARCHAR(11) NULL,
AddressDirection VARCHAR(255) NULL,
Street VARCHAR(255) NULL,
Area INT(11) NULL,
Price INT(11) NULL,
PropertyType VARCHAR(11) NULL,
Relevancy DOUBLE NULL
)") or die(mysql_error());
$database->query("INSERT INTO AddressSearch SELECT ListNum,AddressNum,AddressDirection,Street,Area,Price,'RES', MATCH(AddressNum,AddressDirection,Street) AGAINST('{$mysql['address']}') AS Relevancy FROM `".TBL_RES."` WHERE MATCH (AddressNum,AddressDirection,Street) AGAINST ('{$mysql['address']}');") or die(mysql_error());
$database->query("INSERT INTO AddressSearch SELECT ListNum,AddressNum,AddressDirection,Street, Area, Price,'CIB', MATCH(AddressNum,AddressDirection,Street) AGAINST('{$mysql['address']}') AS Relevancy FROM `".TBL_CIB."` WHERE MATCH (AddressNum,AddressDirection,Street) AGAINST ('{$mysql['address']}');") or die(mysql_error());
$database->query("INSERT INTO AddressSearch SELECT ListNum,AddressNum,AddressDirection,Street,Area,Price,'FAL', MATCH(AddressNum,AddressDirection,Street) AGAINST('{$mysql['address']}') AS Relevancy FROM `".TBL_FAL."` WHERE MATCH (AddressNum,AddressDirection,Street) AGAINST ('{$mysql['address']}');") or die(mysql_error());
$database->query("INSERT INTO AddressSearch SELECT ListNum,AddressNum,AddressDirection,Street,Area,Price,'MUL', MATCH(AddressNum,AddressDirection,Street) AGAINST('{$mysql['address']}') AS Relevancy FROM `".TBL_MUL."` WHERE MATCH (AddressNum,AddressDirection,Street) AGAINST ('{$mysql['address']}');") or die(mysql_error());
// first query, see how many results are actually in the table
$query = $database->query("SELECT * FROM AddressSearch;");
$result = mysql_num_rows($query);