проще для понимания, и более общий ответ выглядит следующим образом:
Представьте динамический 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'--
и пустой пароль, который должен выглядеть ложным.
Это не полное решение, и проверка ввода еще должна быть выполнена, поскольку это не повлияет на другие проблемы, такие как атаки xss, поскольку вы все равно можете поместить javascript в базу данных. Затем, если это зачитано на странице, оно будет отображать его как обычный javascript, в зависимости от какой-либо проверки валидации. Так что лучше всего по-прежнему использовать проверку ввода, но используя параметризованные запросы или хранимые процедуры, чтобы остановить любые атаки SQL.
Источник: http://www.lavamunky.com/2011/11/why-parameterized-queries-stop-sql.html
Вы также получите сообщение об ошибке за попытку использовать переменные в местах, где SQL (и TSQL в данном случае) не поддерживает переменные. IE: 'FROM' clause, единственный параметр для представления списка, разделенного запятыми, в предложении' IN' и т. Д. –
Я не думаю, что это отвечает на вопрос. Вы можете вызвать хранимую процедуру, используя класс SQLParameter, который передает параметры процедуре, но не вызывает sp_executesql. Что происходит со значениями параметров в конкатенированной строке sql? – Ian