Создание безопасных операторов SQL в виде строк - PullRequest
11 голосов
/ 16 ноября 2008

Я использую C # и .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')"

Я смотрю на некоторый код, который создает операторы вставки с помощью 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 ()

Ответы [ 5 ]

17 голосов
/ 16 ноября 2008

Создайте свой объект 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();
7 голосов
/ 16 ноября 2008

Использовать параметризованные команды. Также передайте параметры своему удаленному серверу и получите его для вызова в SQL Server, сохраняя при этом различие между самим SQL и значениями параметров.

Пока вы никогда не смешиваете данные с кодом, все будет в порядке.

4 голосов
/ 31 мая 2012

Исправьте функцию замены цитаты следующим образом:

void string replaceQuotes(string value) {
     string tmp = value;
     tmp = tmp.Replace("'", "''");
     return tmp;
}

Ура! * * 1004

1 голос
/ 16 ноября 2008

Хм. Я согласен со всеми остальными, что вы должны использовать параметризованные запросы, и оставлю это на этом. Но как вы собираетесь передать эти операторы SQL на свой удаленный сервер? У вас есть какой-либо тип сервиса, например, веб-сервис, который будет принимать и выполнять произвольные команды Sql, или ваше клиентское приложение будет напрямую обращаться к БД?

Если вы проходите через какой-то прокси-сервер, то независимо от того, насколько вы дезинфицируете свои данные на клиенте, хакер может просто обойти ваше приложение и запустить службу. В этом случае сделайте то, что рекомендует Cade, и передайте данные, например, в формате XML или в любом другом формате, который вы выберете (JSON, Binary и т.

0 голосов
/ 16 ноября 2008

Чтобы избежать внедрения, вам необходимо отправить данные на удаленный сервер (возможно, в формате XML), а затем на удаленном сервере данные должны быть преобразованы обратно в соответствующие типы данных и использованы в параметризованных запросах или хранимых процессах.

...