Создание безопасных операторов SQL в виде строк
Я использую С# и .NET 3.5. Мне нужно сгенерировать и сохранить некоторые инструкции вставки T-SQL, которые будут выполняться позже на удаленном сервере.
Например, у меня есть массив Employees:
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')"
Я просматриваю код, который создает инструкции insert в String.Format, но это не так. Я рассматривал использование SqlCommand (надеясь сделать что-то вроде этого), но он не предлагает способ комбинировать текст команды с параметрами.
Достаточно ли просто заменить одиночные кавычки и построить строку?
string.Format("INSERT INTO Employees (id, name) VALUES ({0}, '{1}')",
employee.ID,
replaceQuotes(employee.Name)
);
Что мне следует беспокоиться о том, когда вы это делаете? Исходные данные достаточно безопасны, но я не хочу делать слишком много предположений.
EDIT: просто хочу указать, что в этом случае у меня нет SqlConnection или любого способа прямого подключения к SQL Server. Это конкретное приложение должно генерировать операторы sql и ставить их в очередь для выполнения где-то в другом месте - иначе я бы использовал SqlCommand.Parameters.AddWithValue()
Ответы
Ответ 1
Использовать параметризованные команды. Передайте параметры вместе с вашим удаленным сервером, и получите это, чтобы позвонить в SQL Server, все еще сохраняя различие между самим SQL и значениями параметров.
Пока вы никогда не смешиваете данные обработки как код, вы должны быть в порядке.
Ответ 2
Создайте свой объект 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();
Ответ 3
Исправьте функцию замены кавычек следующим образом:
void string replaceQuotes(string value) {
string tmp = value;
tmp = tmp.Replace("'", "''");
return tmp;
}
Ура!
Ответ 4
Хм, я согласен со всеми, что вы должны использовать параметризованные запросы и оставите это на этом. Но как вы собираетесь передавать эти SQL-заявления на ваш удаленный сервер? Есть ли у вас какой-то сервис, например веб-сервис, который будет принимать и выполнять произвольные команды Sql или ваше клиентское приложение сразу попадет в базу данных?
Если вы проходите через какой-то прокси-сервер, то независимо от того, насколько вы дезинфицируете свои данные на клиенте, хакер может просто обойти ваше приложение и воспользоваться сервисом. В этом случае сделайте то, что Cade рекомендует и передает данные как XML, например, или любой другой формат, который вы выберете (JSON, Binary и т.д.). Затем создайте свой SQL прямо перед тем, как выполнить команду.
Ответ 5
Чтобы избежать инъекции, вам необходимо отправить данные на удаленный сервер (возможно, в формате XML), а затем на удаленный сервер, данные должны быть преобразованы обратно в соответствующие типы данных и использованы в параметризованных запросах или сохраненных процедурах.