After a recent security audit of one of our sites we had to do a but of recoding. One particular issue was with sql injection into form fields
As a result I've written a couple of functions that extract database data into arrays from prepared or parametirised queries using the following functions
If this page gets any hits, comments or feedback I'll add some more detail.
dbConnect ($dbA);
$unsafeInput = $_POST['input_field'];
$userArray = $dbA->retrieveAllRecordsFromPreparedQuery ("select * from users where name like ? or address like ?", array ("%".$unsafeInput."%", "%".$unsafeInput."%"));
print_r ($userArray); // use the array here
$unsafeInput_1 = $_POST['input_field_1'];
$unsafeInput_2 = $_POST['input_field_2'];
$unsafeInput_3 = $_POST['input_field_3'];
$userArray = $dbA->retrieveAllRecordsFromPreparedQuery ("select * from students where forename like ? or surname like ? or postcode like ?", array ("%".$unsafeInput_1."%", "%".$unsafeInput_2."%", "%".$unsafeInput_3."%");
print_r ($userArray); // use the array here
function dbConnect(&$dbA) {
global $dbHost,$dbUser,$dbPassword,$dbName;
$dbA = new dbAccess();
$dbStatus = $dbA-> connect($dbHost,$dbUser,$dbPassword,$dbName);
if ($dbStatus == false && $showErrorOnFail==true) {
exit;
}
return ($dbStatus);
}
class dbAccess {
function connect($sql_host_name,$sql_username,$sql_password,$sql_database_name) {
$this->currentDatabase = $sql_database_name;
$this->resID = @mysqli_connect($sql_host_name,$sql_username,$sql_password);
if ($this->resID == FALSE) {
$this->lastError = "Could not connect to mySQL server";
return FALSE;
} else {
if (@mysqli_select_db($this->resID, $sql_database_name)) {
return TRUE;
} else {
return @mysqli_query($this->resID,"create database $sql_database_name");
return FALSE;
}
}
}
function retrieveAllRecordsFromPreparedQuery ($sql_query, $params){
if ($preparedStmt = mysqli_prepare($this->resID, $sql_query)) {
$paramPattern = $this->getPreparedParamPattern ($params);
call_user_func_array('mysqli_stmt_bind_param', array_merge (array($preparedStmt, $paramPattern), $params));
mysqli_stmt_execute($preparedStmt);
$meta = mysqli_stmt_result_metadata($preparedStmt);
$fieldNames = array();
while ($field = mysqli_fetch_field($meta)) {
$fieldNames[] = $field->name;
}
$resultRow = array($preparedStmt);
foreach($fieldNames as $value) {
$resultRow[] = &$$value;
}
call_user_func_array('mysqli_stmt_bind_result', $resultRow);
$result = array();
while(mysqli_stmt_fetch($preparedStmt)) {
$thisRow = array();
foreach($fieldNames as $value) {
$thisRow[$value] = $$value;
}
$result[] = $thisRow;
}
mysqli_stmt_close($preparedStmt);
return $result;
} else {
return "ERROR";
}
}
function getPreparedParamPattern ($params){
$paramPattern = "";
foreach ($params as $thisParam) {
if (is_string($thisParam)) {
$paramPattern .= "s";
} elseif (is_int($thisParam)) {
$paramPattern .= "i";
} elseif (is_float($thisParam)) {
$paramPattern .= "d";
} else {
die("invalid prepare type");
}
}
return $paramPattern;
}
}