freeCodeCamp/guide/russian/security/query-parameterization/index.md

4.3 KiB
Raw Blame History

title localeTitle
Query Parameterization Параметрирование запроса

Параметрирование запроса

Обычная ошибка при подключении вашей программы к базе данных - это принять вход пользователя и применить его непосредственно к базе данных, не проверив его в первую очередь. Это опасная привычка, и вы можете услышать, что более опытные разработчики предупреждают других о том, что они «дезинфицируют ввод» или «параметризовать запросы».

Начнем с краткого примера, демонстрирующего проблему:

(следующие фрагменты написаны на C # для MySQL, но концепция применима к любому языку и базе данных)

Проблема

public void RetrieveEmployeeInfo(string username) 
 { 
    using (var connection = new MySqlConnection("valid_connection_string")) 
    { 
        var query = "SELECT * FROM EMPLOYEES WHERE USERNAME = '" + username + "'"; 
 
        using (var command = new MySqlCommand(query, connection)) 
        { 
            var reader = command.ExecuteReader(); 
            while (reader.Read()) 
            { 
                // do something with the results of your query, like display the employee 
            } 
        } 
    } 
 } 

На первый взгляд это может показаться довольно безобидным. Если пользователь вводит «JDOE» в вашу программу и передается этой функции, вы в конечном итоге выполняете такой запрос:

SELECT * FROM EMPLOYEES WHERE USERNAME = 'JDOE'; 

Проблема становится более очевидной, если вы считаете, что происходит, если пользователь не вводит то, что вы ожидаете. Что делать, если они набирают что-то вроде JDOE'; DROP TABLE EMPLOYEES; -- ? Теперь ваша строка запроса будет выглядеть так, что выберет информацию о сотруднике, а затем удалит всю таблицу РАБОТНИКОВ!

SELECT * FROM EMPLOYEES WHERE USERNAME = 'JDOE'; DROP TABLE EMPLOYEES; --' 

Решение

Чтобы предотвратить такие проблемы, мы можем параметризовать наши запросы. Давайте посмотрим на другой пример:

public void RetrieveEmployeeInfo(string username) 
 { 
    using (var connection = new MySqlConnection("valid_connection_string")) 
    { 
        var query = "SELECT * FROM EMPLOYEES WHERE USERNAME = @username"; 
 
        using (var command = new MySqlCommand(query, connection)) 
        { 
            command.Parameters.AddWithValue("username", username); 
 
            var reader = command.ExecuteReader(); 
            while (reader.Read()) 
            { 
                // do something with the results of your query, like display the employee 
            } 
        } 
    } 
 } 

Теперь, что произойдет, если пользователь вводит в JDOE'; DROP TABLE EMPLOYEES; -- ? Наша программа заканчивает выполнение запроса, подобного этому, и, не найдя сотрудника, чье имя пользователя действительно соответствует этому вводу, просто не возвращает записей.

SELECT * FROM EMPLOYEES WHERE USERNAME = 'JDOE\'; DROP TABLE EMPLOYEES; --' 

Независимо от того, какой язык или база данных вы используете, если вы рассматриваете запрос базы данных с использованием пользовательского ввода, проверьте документацию для правильного способа параметризации запросов.