Jak sugerują powyższe komentarze, warto używać parametrów zapytania, aby zabezpieczyć się przed wstrzyknięciem SQL.
Pytałeś o przykład, jak można zrobić coś złośliwego. W rzeczywistości nie musi być nawet złośliwy. Każdy niewinny ciąg, który zgodnie z prawem zawiera apostrof, może zepsuć zapytanie SQL. Złośliwe wstrzyknięcie SQL wykorzystuje tę słabość.
Słabość jest naprawiana przez oddzielenie wartości dynamicznych od zapytania SQL do momentu przeanalizowania zapytania. Używamy symboli zastępczych parametrów zapytania w ciągu SQL, a następnie używamy prepare()
by go przeanalizować, a następnie połączyć wartości podczas execute()
przygotowane zapytanie. W ten sposób pozostaje bezpieczny.
Oto jak napisałbym twoją funkcję. Zakładam, że używam PDO który obsługuje nazwane parametry zapytania. Zalecam używanie PDO zamiast 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;
}