Mysql
 sql >> Database >  >> RDS >> Mysql

Qual è un modo migliore per rendere questo inserto più sicuro e protetto da iniezione e manipolazione

Come suggeriscono i commenti precedenti, vale la pena utilizzare i parametri di query per proteggersi dall'iniezione di SQL.

Hai chiesto un esempio di come si possa fare qualcosa di dannoso. In effetti, non ha nemmeno bisogno di essere dannoso. Qualsiasi stringa innocente che contenga legittimamente un apostrofo potrebbe interrompere la tua query SQL. L'iniezione di SQL dannosa sfrutta questa debolezza.

Il punto debole viene risolto mantenendo i valori dinamici separati dalla query SQL fino al termine dell'analisi della query. Utilizziamo i segnaposto dei parametri di query nella stringa SQL, quindi utilizziamo prepare() per analizzarlo, quindi combinare i valori quando execute() la query preparata. In questo modo resta al sicuro.

Ecco come scriverei la tua funzione. Presumo che utilizzi PDO che supporta parametri di query denominati. Consiglio di usare PDO invece di 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;
}