2011-02-03 2 views
52

Что именно происходит в фоновом режиме, поэтому SQLParameter предотвращает атаки SQL Inection в .NET-параметризованном запросе? Разве это просто лишает всех подозреваемых персонажей или есть что-то еще?Как SQLParameter предотвращает инъекцию SQL?

Кто-нибудь там проверил, чтобы узнать, что на самом деле попадает на SQL Server при передаче вредоносного ввода?

Похожие: Can you use a SQLParameter in the SQL FROM statement?

ответ

54

В основном, при выполнении SQLCommand с помощью SQLParameters, параметры никогда не вставляются непосредственно в заявлении. Вместо этого вызывается системная хранимая процедура с именем sp_executesql и задана строка SQL и массив параметров.

При использовании как таковые параметры изолированы и обрабатываются как данные, вместо того, чтобы анализироваться из инструкции (и, возможно, ее изменить), поэтому параметры, которые не могут быть выполнены, никогда не могут быть «выполнены». Вы просто получите большую жирную ошибку, так как значение параметра некорректно.

+1

Вы также получите сообщение об ошибке за попытку использовать переменные в местах, где SQL (и TSQL в данном случае) не поддерживает переменные. IE: 'FROM' clause, единственный параметр для представления списка, разделенного запятыми, в предложении' IN' и т. Д. –

+0

Я не думаю, что это отвечает на вопрос. Вы можете вызвать хранимую процедуру, используя класс SQLParameter, который передает параметры процедуре, но не вызывает sp_executesql. Что происходит со значениями параметров в конкатенированной строке sql? – Ian

9

«коллекция параметров, такие как SqlParameterCollection обеспечивают проверку типов и проверку длиной Если используется набор параметров, ввод обрабатываются как буквенное значение, и SQL Server не обрабатывает его как исполняемый код.. Дополнительным преимуществом использования коллекции параметров является то, что вы можете применять проверки типа и длины. Значения вне диапазона запускают исключение. Это хороший пример защиты в глубину ».

http://msdn.microsoft.com/en-us/library/ff648339.aspx

4

При использовании параметризованных запросов поверхность атаки сводится к обезьяне с параметрами.

Используйте SqlParameters, но не забывайте о переполнении, нижнем и неизмененном параметрах. Например, если метод «proc buy_book (@price money»), злоумышленник попытается обмануть приложение для работы с @price, установленным на 0.01, или попытаться заставить приложение сделать что-то интересное, отправив что-то, что вызывает переполнение. Sql Переполнение, как правило, не интересно (т.е. они просто вызывают исключения, вы вряд ли сможете написать примыкающей памяти)

21

проще для понимания, и более общий ответ выглядит следующим образом:

Представьте динамический SQL-запрос:

sqlQuery='SELECT * FROM custTable WHERE User=' + Username + ' AND Pass=' + password

простая инъекция SQL будет просто поместить имя пользователя в качестве ' OR 1=1--

Это будет эффективно сделать запрос SQL:

sqlQuery='SELECT * FROM custTable WHERE User='' OR 1=1-- ' AND PASS=' + password

Это говорит выбрать всех клиентов, где их имя пользователя пустым ('') или 1=1, который является логическим, приравнивая к истине. Затем он использует --, чтобы прокомментировать остальную часть запроса. Таким образом, это распечатает таблицу клиентов или позволит вам делать с ней все, что вы хотите.

Теперь параметризованные запросы делают это по-разному, с кодом, как:

sqlQuery='SELECT * FROM custTable WHERE User=? AND Pass=?' parameters.add("User", username) parameters.add("Pass", password)

, где имя пользователя и пароль являются переменными, указывающие на соответствующий занесены имя пользователя и пароль.

Теперь вы можете подумать, что это ничего не меняет. Конечно, вы все еще можете просто положить в имени пользователя поле что-то вроде никто OR 1 = 1' -, фактически делая запрос:

sqlQuery='SELECT * FROM custTable WHERE User=Nobody OR 1=1'-- AND Pass=?'

И это, казалось бы, как действительный аргумент. Но вы ошибаетесь.

Как работают параметризованные запросы, запрос SQL отправляется как запрос, и база данных точно знает, что будет делать этот запрос, и только после этого он будет вставлять имя пользователя и пароли только в качестве значений. Это означает, что они не могут повлиять на запрос, поскольку база данных уже знает, что будет делать запрос. Поэтому в этом случае он будет искать имя пользователя Nobody OR 1=1'-- и пустой пароль, который должен выглядеть ложным.

Это не полное решение, и проверка ввода еще должна быть выполнена, поскольку это не повлияет на другие проблемы, такие как атаки , поскольку вы все равно можете поместить javascript в базу данных. Затем, если это зачитано на странице, оно будет отображать его как обычный javascript, в зависимости от какой-либо проверки валидации. Так что лучше всего по-прежнему использовать проверку ввода, но используя параметризованные запросы или хранимые процедуры, чтобы остановить любые атаки SQL.

Источник: http://www.lavamunky.com/2011/11/why-parameterized-queries-stop-sql.html

+0

Любите способ, которым вы объяснили :-) чистое и точное. – Sujith

Смежные вопросы