C# и MySQL Коннектор.NET - Какой-либо способ предотвратить Атаки с использованием кода на SQL в универсальном классе?

Моя идея состоит в том, чтобы создать некоторые универсальные классы для, Вставляют/Обновляют/Выбирают через C# (3.5) приложение Winforms, говорящее с базой данных MySQL через MySQL Коннектор.NET 6.2.2.

Например:

public void Insert(string strSQL)
{
   if (this.OpenConnection() == true)
   {
       MySqlCommand cmd = new MySqlCommand(strSQL, connection);
       cmd.ExecuteNonQuery();
       this.CloseConnection();
   }
}

Затем отовсюду в программе я могу выполнить запрос с/без вводом данных пользователем, просто передав строку SQL-запроса.

Чтение вокруг на ТАК начинает давать мне признак, что это может привести к атакам с использованием кода на SQL (для любых значений ввода данных пользователем). Имеет ли так или иначе вычищение введенного strSQL, или я должен пойти и создать отдельные параметризированные запросы в каждом методе, который должен сделать функцию базы данных?

UPDATE1:

Мое Конечное решение выглядит примерно так:

public void Insert(string strSQL,string[,] parameterValue)
{
   if (this.OpenConnection() == true)
   {
       MySqlCommand cmd = new MySqlCommand(strSQL, connection);

       for(int i =0;i< (parameterValue.Length / 2);i++)
       {                        
       cmd.Parameters.AddWithValue(parameterValue[i,0],parameterValue[i,1]);          
       }

       cmd.ExecuteNonQuery();
       this.CloseConnection();
   }}
9
задан Stecya 18 May 2011 в 14:16
поделиться

8 ответов

Вы определенно должны использовать параметризованные запросы, чтобы обезопасить себя.

Однако не обязательно каждый раз вручную создавать параметризованные запросы. Вы можете модифицировать предоставленный вами общий метод, чтобы он принимал коллекцию MySqlParameters:

public void Insert(string strSQL, List<MySqlParameter> params)
{
    if(this.OpenConnection() == true)
    {
        MySqlCommand cmd = new MySqlCommand(strSQL, connection)
        foreach(MySqlParameter param in params)
            cmd.Parameters.Add(param);

        cmd.ExecuteNonQuery();
        this.CloseConnection();
    }
}

Я также должен упомянуть, что вы должны быть ОЧЕНЬ осторожны с очисткой соединений после завершения их использования (обычно это делается в блоке using, но я не вижу такого уровня детализации в вашем примере кода).

11
ответ дан 4 December 2019 в 07:47
поделиться

Параметризация очень проста. Намного проще, чем чистка SQL-запросов, и менее беспорядочно и менее подвержено ошибкам, чем экранирование вручную.

Немного отредактировано копирование / вставка с этой страницы руководства , потому что мне лень:

// User input here
Console.WriteLine("Enter a continent e.g. 'North America', 'Europe': ");
string userInput = Console.ReadLine();

string sql = "SELECT Name, HeadOfState FROM Country WHERE Continent=@Continent";
MySqlCommand cmd = new MySqlCommand(sql, conn);
cmd.Parameters.AddWithValue("@Continent", userInput);

using (MySqlDataReader dr = cmd.ExecuteReader())
{
    // etc.
}

Это было не так уж сложно, правда? :)

11
ответ дан 4 December 2019 в 07:47
поделиться

Вы действительно не можете этого сделать - вам нужно написать синтаксический анализатор SQL, который, мягко говоря, нетривиален и подвержен ошибкам.

Будьте осторожны и параметризуйте свои запросы.

1
ответ дан 4 December 2019 в 07:47
поделиться

ДА, вам нужно создавать параметризованные запросы, что-либо другое создаст риск SQL-инъекции

1
ответ дан 4 December 2019 в 07:47
поделиться

если вы используете MySqlParameter и не генерируете простые строковые запросы, вы в безопасности.

1
ответ дан 4 December 2019 в 07:47
поделиться

Я ожидал, что будет довольно сложно очистить необработанный текст, который будет использоваться для SQL. Если возможно, я бы попытался использовать параметризованные операции.

Одно исключение - если вы не раскрывали функцию публично и никогда не передавали строку, созданную из необработанного пользовательского ввода.

1
ответ дан 4 December 2019 в 07:47
поделиться

Невозможно обнаружить SQL-инъекцию постфактум (другими словами, после создания строки динамического запроса невозможно отличить «настоящий» SQL от любого внедренный SQL).

Если ваше намерение состоит в том, чтобы позволить пользователям выполнять произвольный SQL, то, похоже, вас не слишком беспокоит SQL-инъекция (поскольку это цель SQL-инъекции).

1
ответ дан 4 December 2019 в 07:47
поделиться

Я бы предложил использовать объекты IDataParameter для параметризации ваших запросов.

1
ответ дан 4 December 2019 в 07:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: