Як SQLParameter запобігає введенню SQL?


76

Що саме відбувається у фоновому режимі, що робить його таким SQLParameter запобігає атакам SQL Inection у запиті, параметризованому .NET? Це просто зачищення підозрілих персонажів чи щось інше?

Хтось там перевіряв, що насправді потрапляє на SQL Server, коли ви передаєте зловмисне введення?

Пов’язане: Чи можете ви використовувати параметр SQL в операторі SQL FROM?

Відповіді:


78

В основному, коли ви виконуєте SQLCommandвикористання SQLParameters, параметри ніколи не вставляються безпосередньо в оператор. Натомість викликається збережена в системі процедура, яка sp_executesqlотримує рядок SQL та масив параметрів.

При використанні таких параметрів паралельно виділяються та обробляються як дані, замість того, щоб їх аналізувати (і, можливо, змінювати їх), тому те, що містять параметри, ніколи не може бути "виконано". Ви просто отримаєте велику жирову помилку про те, що значення параметра якимось чином недійсне.


1
Ви також отримаєте помилку за спробу використання змінних у місцях, де SQL (і TSQL у цьому випадку) не підтримує змінні. IE: FROMречення, один параметр, що представляє список розділених комами в INреченні тощо
OMG Ponies

1
Я не думаю, що це відповідає на питання. Ви можете викликати збережену процедуру за допомогою класу SQLParameter, який передає параметри процедурі, але не викликає sp_executesql. Що відбувається зі значеннями параметрів у зв’язаному рядку sql?
Ян

58

Більш легка для розуміння та більш загальна відповідь виглядає так:

Уявіть динамічний запит 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'--та порожній пароль, який повинен бути помилковим.

Однак це не повноцінне рішення, і перевірку вводу все одно потрібно буде зробити, оскільки це не вплине на інші проблеми, такі як атаки, оскільки ви все ще можете помістити javascript у базу даних. Потім, якщо це прочитано на сторінці, воно відображатиметься як звичайний javascript, залежно від будь-якої перевірки вихідних даних. Тож найкраще все-таки використовувати перевірку вводу, але використовувати параметризовані запити або збережені процедури для зупинки будь-яких атак SQL.

Джерело: http://www.lavamunky.com/2011/11/why-parameterized-queries-stop-sql.html


10

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

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


5

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

Використовуйте SqlParameters, але не забувайте про параметри переповнення, переповнення та непроверені параметри. Наприклад, якщо метод "proc buy_book (@price money)", зловмисний зловмисник намагатиметься обдурити додаток, щоб він працював із @priceset to 0.01, або намагається змусити програму зробити щось цікаве, подавши щось, що викликає переповнення. Переповнення Sql, як правило, нецікаве (тобто вони просто викликають винятки, ви навряд чи зможете писати в сусідню пам’ять)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.