Моя идея состоит в том, чтобы создать некоторые универсальные классы для, Вставляют/Обновляют/Выбирают через 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();
}}
Вы определенно должны использовать параметризованные запросы, чтобы обезопасить себя.
Однако не обязательно каждый раз вручную создавать параметризованные запросы. Вы можете модифицировать предоставленный вами общий метод, чтобы он принимал коллекцию 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
, но я не вижу такого уровня детализации в вашем примере кода).
Параметризация очень проста. Намного проще, чем чистка 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.
}
Это было не так уж сложно, правда? :)
Вы действительно не можете этого сделать - вам нужно написать синтаксический анализатор SQL, который, мягко говоря, нетривиален и подвержен ошибкам.
Будьте осторожны и параметризуйте свои запросы.
ДА, вам нужно создавать параметризованные запросы, что-либо другое создаст риск SQL-инъекции
если вы используете MySqlParameter
и не генерируете простые строковые запросы, вы в безопасности.
Я ожидал, что будет довольно сложно очистить необработанный текст, который будет использоваться для SQL. Если возможно, я бы попытался использовать параметризованные операции.
Одно исключение - если вы не раскрывали функцию публично и никогда не передавали строку, созданную из необработанного пользовательского ввода.
Невозможно обнаружить SQL-инъекцию постфактум (другими словами, после создания строки динамического запроса невозможно отличить «настоящий» SQL от любого внедренный SQL).
Если ваше намерение состоит в том, чтобы позволить пользователям выполнять произвольный SQL, то, похоже, вас не слишком беспокоит SQL-инъекция (поскольку это цель SQL-инъекции).
Я бы предложил использовать объекты IDataParameter для параметризации ваших запросов.