Когда в статьях говорится о параметризованных запросах, останавливающих атаки SQL, они на самом деле не объясняют почему, часто это так: «Да, не спрашивайте почему» - возможно, потому, что они сами не знают.Верным признаком плохого воспитателя является тот, который не может признать, что они ничего не знают.Но я отвлекся.Когда я говорю, что совершенно понятно, что запутаться - это просто.Представьте себе динамический 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=?'
И это может показаться действительным аргументом.Но вы были бы неправы.
Способ работы параметризованных запросов заключается в том, что sqlQuery отправляется как запрос, и база данных точно знает, что будет делать этот запрос, и только тогда она будет вставлять имя пользователя и пароли.просто как ценности.Это означает, что они не могут повлиять на запрос, потому что база данных уже знает, что будет делать запрос.Таким образом, в этом случае он будет искать имя пользователя «Nobody OR 1 = 1 '-» и пустой пароль, который должен быть ложным.
Это не полное решение и проверка вводавсе еще нужно будет сделать, так как это не повлияет на другие проблемы, такие как атаки XSS, так как вы все равно можете поместить javascript в базу данных.Затем, если это будет считано на странице, он будет отображаться как обычный javascript, в зависимости от проверки вывода.Поэтому лучше всего по-прежнему использовать проверку ввода, но использовать параметризованные запросы или хранимые процедуры, чтобы остановить любые атаки SQL.