Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Was ist ein besserer Weg, um diesen Einsatz sicherer und sicherer vor Injektion und Manipulation zu machen?

Wie die obigen Kommentare nahelegen, lohnt es sich, Abfrageparameter zu verwenden, um sich vor SQL-Injection zu schützen.

Sie haben nach einem Beispiel gefragt, wie etwas Böswilliges getan werden könnte. Tatsächlich muss es nicht einmal bösartig sein. Jede unschuldige Zeichenfolge, die berechtigterweise ein Apostroph enthält, könnte Ihre SQL-Abfrage beschädigen. Böswillige SQL-Einschleusung nutzt diese Schwäche aus.

Die Schwachstelle wird behoben, indem dynamische Werte von Ihrer SQL-Abfrage getrennt gehalten werden, bis die Abfrage analysiert wurde. Wir verwenden Platzhalter für Abfrageparameter in der SQL-Zeichenfolge und verwenden dann prepare() um es zu analysieren und danach die Werte zu kombinieren, wenn Sie execute() ausführen die vorbereitete Abfrage. So bleibt es sicher.

Hier ist, wie ich Ihre Funktion schreiben würde. Ich gehe davon aus, dass ich PDO verwende die benannte Abfrageparameter unterstützt. Ich empfehle die Verwendung von PDO anstelle von 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;
}