Страницы

Поиск по вопросам

воскресенье, 22 декабря 2019 г.

Каким образом использование предопределённых (параметризованных) выражений (запросов) помогает избежать SQL-инъекции?

#sql #безопасность


Одним из способов предотвращения SQL-инъекций считается применение параметризованных
запросов, вместо прямой подстановки пользовательских данных в запрос, например:

private static void UpdateDemographics(Int32 customerID,
string demoXml, string connectionString)
{
    // Update the demographics for a store, which is stored 
    // in an xml column. 
    string commandText = "UPDATE Sales.Store SET Demographics = @demographics "
        + "WHERE CustomerID = @ID;";

    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        SqlCommand command = new SqlCommand(commandText, connection);
        command.Parameters.Add("@ID", SqlDbType.Int);
        command.Parameters["@ID"].Value = customerID;

        // Use AddWithValue to assign Demographics.
        // SQL Server will implicitly convert strings into XML.
        command.Parameters.AddWithValue("@demographics", demoXml);

        try
        {
            connection.Open();
            Int32 rowsAffected = command.ExecuteNonQuery();
            Console.WriteLine("RowsAffected: {0}", rowsAffected);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
}


То есть имеется некий запрос, в который мы передаём полученные впоследствии от пользователя
параметры. Но чем такой способ отличается от непосредственной подстановки в запрос
параметров пользователя? Ведь мы по-прежнему можем поместить код-инъекцию в @ID, передав
таким образом запрос на выполнение. В чем принципиальное преимущество?
    


Ответы

Ответ 1



Если выполняется честный prepare, то текст запроса передаётся отдельно, а данные для него - отдельно, по специальному протоколу ("привет, выполни тот запрос, первый параметр для него - это следующие 8 байт, а второй - следующие 20"). Данные в запрос никогда не подставляются и сервер в принципе не может перепутать данные и запрос. Если выполняется эмуляция подготовленного запроса - то код библиотеки, выполняющей запрос, берёт на себя ответственность за корректное экранирование всех подставляемых данных. Выполняется честный prepare или его эмуляция - надо выяснять для конкретной библиотеки (возможно, это отдельная настройка конфигурации библиотеки). Но если используется что-то общеизвестное, стандартное и актуальной версии - то оба варианта достаточно безопасны.

Комментариев нет:

Отправить комментарий