Как избежать SQL-инъекций без параметров - PullRequest
107 голосов
/ 26 мая 2009

У нас здесь еще одно обсуждение использования параметризованных SQL-запросов в нашем коде. У нас есть две стороны в обсуждении: я и некоторые другие, которые говорят, что мы всегда должны использовать параметры для защиты от SQL-инъекций, и другие парни, которые не считают это необходимым. Вместо этого они хотят заменить одиночные апострофы двумя апострофами во всех строках, чтобы избежать SQL-инъекций. Все наши базы данных работают на Sql Server 2005 или 2008, а наша база кода работает на .NET Framework 2.0.

Позвольте мне привести простой пример на C #:

Я хочу, чтобы мы использовали это:

string sql = "SELECT * FROM Users WHERE Name=@name";
SqlCommand getUser = new SqlCommand(sql, connection);
getUser.Parameters.AddWithValue("@name", userName);
//... blabla - do something here, this is safe

Пока другие парни хотят это сделать:

string sql = "SELECT * FROM Users WHERE Name=" + SafeDBString(name);
SqlCommand getUser = new SqlCommand(sql, connection);
//... blabla - are we safe now?

Где функция SafeDBString определяется следующим образом:

string SafeDBString(string inputValue) 
{
    return "'" + inputValue.Replace("'", "''") + "'";
}

Теперь, пока мы используем SafeDBString для всех строковых значений в наших запросах, мы должны быть в безопасности. Правильно?

Есть две причины использовать функцию SafeDBString. Во-первых, это так, как это было сделано с давних пор, а во-вторых, легче отлаживать операторы SQL, поскольку вы видите точный запрос, который выполняется в базе данных.

Итак. Мой вопрос заключается в том, действительно ли достаточно использовать функцию SafeDBString, чтобы избежать атак с использованием SQL-инъекций. Я пытался найти примеры кода, который нарушает эту меру безопасности, но я не могу найти никаких примеров этого.

Есть ли кто-нибудь, кто может сломать это? Как бы вы это сделали?

EDIT: Подведем итоги ответов:

  • Никто еще не нашел способа обойти SafeDBString на Sql Server 2005 или 2008. Это хорошо, я думаю?
  • В нескольких ответах указывалось, что вы получаете прирост производительности при использовании параметризованных запросов. Причина в том, что планы запросов можно использовать повторно.
  • Мы также согласны с тем, что использование параметризованных запросов дает более читаемый код, который легче поддерживать
  • Кроме того, всегда проще использовать параметры, чем использовать различные версии SafeDBString, преобразования строки в число и преобразования строки в дату.
  • Используя параметры, вы получаете автоматическое преобразование типов, что особенно полезно при работе с датами или десятичными числами.
  • И, наконец: Не пытайтесь самостоятельно обеспечивать безопасность , как писал JulianR. Поставщики баз данных тратят много времени и денег на безопасность. Мы никак не можем добиться большего успеха, и нет причин, по которым мы должны стараться делать их работу.

Так что, хотя никто не смог нарушить простую защиту функции SafeDBString, у меня появилось много других хороших аргументов. Спасибо!

Ответы [ 21 ]

0 голосов
/ 26 мая 2009

Вот несколько причин использовать параметризованные запросы:

  1. Безопасность - Уровень доступа к базе данных знает, как удалять или экранировать элементы, которые не разрешены в данных.
  2. Разделение проблем - Мой код не отвечает за преобразование данных в формат, который нравится базе данных.
  3. Нет избыточности - мне не нужно включать сборку или класс в каждый проект, который выполняет форматирование / экранирование этой базы данных; он встроен в библиотеку классов.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...