Подтвердить что ты не робот

Как SQLParameter предотвращает внедрение SQL?

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

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

Связанный: Можете ли вы использовать SQLParameter в инструкции SQL FROM?

4b9b3361

Ответ 1

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

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

Ответ 2

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

Представьте динамический запрос 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, которое является логическим, приравнивая true. Затем он использует --, чтобы прокомментировать остальную часть запроса. Таким образом, это распечатает всю таблицу клиентов или позволит вам делать все, что вам нужно.

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

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

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

Теперь, на этот момент, вы можете подумать, что это ничего не меняет. Конечно, вы все равно можете просто ввести в поле имени пользователя что-то вроде Nobody 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

Ответ 3

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

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

Ответ 4

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

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