Mysql
 sql >> Base de données >  >> RDS >> Mysql

Quelle meilleure façon de rendre cet insert plus sûr et à l'abri des injections et des manipulations

Comme le suggèrent les commentaires ci-dessus, il vaut la peine d'utiliser des paramètres de requête pour vous protéger de l'injection SQL.

Vous avez demandé un exemple de la façon dont quelque chose de malveillant pourrait être fait. En fait, il n'a même pas besoin d'être malveillant. Toute chaîne innocente contenant légitimement une apostrophe pourrait casser votre requête SQL. L'injection SQL malveillante tire parti de cette faiblesse.

La faiblesse est corrigée en gardant les valeurs dynamiques séparées de votre requête SQL jusqu'à ce que la requête soit analysée. Nous utilisons des espaces réservés pour les paramètres de requête dans la chaîne SQL, puis utilisons prepare() pour l'analyser, puis combiner les valeurs lorsque vous execute() la requête préparée. De cette façon, il reste en sécurité.

Voici comment j'écrirais votre fonction. Je suppose que j'utilise PDO qui prend en charge les paramètres de requête nommés. Je recommande d'utiliser PDO au lieu de 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;
}