Както показват коментарите по-горе, струва си да използвате параметри на заявката, за да се предпазите от SQL инжектиране.
Поискахте пример как може да се направи нещо злонамерено. Всъщност дори не е необходимо да е злонамерен. Всеки невинен низ, който законно съдържа апостроф, може да наруши вашата SQL заявка. Злонамереното SQL инжектиране се възползва от тази слабост.
Слабостта се коригира чрез запазване на динамичните стойности отделно от вашата SQL заявка, докато заявката не бъде анализирана. Използваме контейнери за параметри на заявката в SQL низа, след което използваме prepare()
за да го анализирате и след това комбинирате стойностите, когато execute()
подготвената заявка. По този начин остава безопасно.
Ето как бих написал вашата функция. Предполагам, че използвам PDO който поддържа именувани параметри на заявката. Препоръчвам да използвате PDO вместо Mysqli.
function updateProfile( $vars, $userId ) {
$db = new Database();
$safeArray = [
"gradYear",
"emailAddress",
"token",
"iosToken",
"country",
"birthYear",
"userDescription",
];
// Filter $vars to include only keys that exist in $safeArray.
$data = array_intersect_keys($vars, array_flip($safeArray));
// This might result in an empty array if none of the $vars keys were valid.
if (count($data) == 0) {
trigger_error("Error: no valid columns named in: ".print_r($vars, true));
$response = ["response" => 400, "title" => "no valid fields found"];
return $response;
}
// Build list of update assignments for SET clause using query parameters.
// Remember to use back-ticks around column names, in case one conflicts with an SQL reserved keyword.
$updateAssignments = array_map(function($column) { return "`$column` = :$column"; }, array_keys($data));
$updateString = implode(",", $updateAssignments);
// Add parameter for WHERE clause to $data.
// This must be added after $data is used to build the update assignments.
$data["userIdWhere"] = $userId;
$sqlStatement = "update users set $updateString where userId = :userIdWhere";
$stmt = $db->prepare($sqlStatement);
if ($stmt === false) {
$err = $db->errorInfo();
trigger_error("Error: {$err[2]} preparing SQL query: $sqlStatement");
$response = ["response" => 500, "title" => "database error, please report it to the site administrator"];
return $response;
}
$ok = $stmt->execute($data);
if ($ok === false) {
$err = $stmt->errorInfo();
trigger_error("Error: {$err[2]} executing SQL query: $sqlStatement");
$response = ["response" => 500, "title" => "database error, please report it to the site administrator"];
return $response;
}
$response = ["response" => 200, "title" => "update successful"];
return $response;
}