Создание безопасных операторов SQL в виде строк
-
08-07-2019 - |
Вопрос
Я использую С# и .NET 3.5.Мне нужно сгенерировать и сохранить несколько операторов вставки T-SQL, которые будут выполнены позже на удаленном сервере.
Например, у меня есть массив сотрудников:
new Employee[]
{
new Employee { ID = 5, Name = "Frank Grimes" },
new Employee { ID = 6, Name = "Tim O'Reilly" }
}
и мне нужно получить массив строк, например:
"INSERT INTO Employees (id, name) VALUES (5, 'Frank Grimes')",
"INSERT INTO Employees (id, name) VALUES (6, 'Tim O''Reilly')"
Я смотрю на код, который создает операторы вставки с помощью String.Format, но это неправильно.Я рассматривал возможность использования SqlCommand (надеясь сделать что-то вроде этого), но он не предлагает возможности объединить текст команды с параметрами.
Достаточно ли просто заменить одинарные кавычки и построить строку?
string.Format("INSERT INTO Employees (id, name) VALUES ({0}, '{1}')",
employee.ID,
replaceQuotes(employee.Name)
);
Чего мне следует опасаться при этом?Исходные данные вполне безопасны, но я не хочу делать слишком много предположений.
РЕДАКТИРОВАТЬ:Просто хочу отметить, что в данном случае у меня нет SqlConnection или какого-либо способа прямого подключения к SQL Server.Это конкретное приложение должно генерировать инструкции sql и ставить их в очередь для выполнения где-то еще - в противном случае я бы использовал SqlCommand.Parameters.AddWithValue().
Решение
Используйте параметризованные команды. Также передайте параметры на ваш удаленный сервер и получите его для вызова в SQL Server, сохраняя при этом различие между самим SQL и значениями параметров.
Если вы никогда не смешиваете обработку данных как кода, все будет в порядке.
Другие советы
Создайте свой объект SqlCommand примерно так:
SqlCommand cmd = new SqlCommand(
"INSERT INTO Employees (id, name) VALUES (@id, @name)", conn);
SqlParameter param = new SqlParameter();
param.ParameterName = "@id";
param.Value = employee.ID;
cmd.Parameters.Add(param);
param = new SqlParameter();
param.ParameterName = "@name";
param.Value = employee.Name;
cmd.Parameters.Add(param);
cmd.ExecuteNonQuery();
Исправьте функцию замены кавычек следующим образом:
void string replaceQuotes(string value) {
string tmp = value;
tmp = tmp.Replace("'", "''");
return tmp;
}
Ваше здоровье!
Хм, я согласен со всеми остальными, что вы должны использовать параметризованные запросы, и оставлю это на этом. Но как вы собираетесь передать эти операторы SQL на свой удаленный сервер? У вас есть какой-то тип сервиса, например, веб-сервис, который будет принимать и выполнять произвольные команды Sql, или ваше клиентское приложение будет напрямую обращаться к БД?
Если вы проходите через какой-то прокси-сервер, то независимо от того, насколько вы дезинфицируете свои данные на клиенте, хакер может просто обойти ваше приложение и запустить службу. В этом случае делайте то, что рекомендует Cade, и передавайте данные, например, в формате XML или в любом другом формате, который вы выберете (JSON, Binary и т.
Чтобы избежать внедрения, вам необходимо отправить данные на удаленный сервер (возможно, в формате XML), а затем на удаленном сервере данные должны быть преобразованы обратно в соответствующие типы данных и использованы в параметризованных запросах или хранимых процессах. р>