Більш легка для розуміння та більш загальна відповідь виглядає так:
Уявіть динамічний запит 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)
де ім'я користувача та пароль - це змінні, що вказують на пов'язані введені ім'я користувача та пароль.
Зараз на цьому етапі, ви можете подумати, це взагалі нічого не змінює. Звичайно, ви все ще можете просто ввести в поле імені користувача щось на зразок Ніхто АБО 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
FROM
речення, один параметр, що представляє список розділених комами вIN
реченні тощо