Чи варто все-таки використовувати QUOTENAME для захисту від ін'єкційних атак?


9

Я сьогодні переглянув стару збережену процедуру і помітив, що вона використовується quotenameна вхідних параметрах. Після деякого копання, щоб зрозуміти, що це робить саме я натрапив на цей сайт . Зараз я розумію, що це робить і як ним користуватися, але на сайті йдеться, що він використовується як пом'якшення від атак SQL Injection. Коли я розробляв додатки, які безпосередньо запитували базу даних, використовуючи asp.net, я б використовував параметри ADO.Net, щоб передавати введення користувача як буквальне значення, і ніколи не переймався захистом його в своїх збережених процедурах.

Зараз я пишу збережену процедуру, яку використовуватимуть додатки, які я не пишу, тому мені потрібно спробувати захистити від нападів ін'єкцій на рівні процедури, це quotenameнайкращий спосіб зробити це чи є нова функція / краще метод?

Код, який отримав мене за цією схемою думки ( @parm1є вхідним параметром користувача):

'SELECT project [Project], project_desc [Description], 
        customer [Customer], cpnyid [Company]
FROM PJPROJ (nolock)
where project like ' + quotename(@parm1,'''') + '

Відповіді:


17

Так, у цій області все мало змінилося, ви повинні використовувати quotenameдля будь-яких імен об'єктів SQL-сервера, які використовуються в динамічному SQL (особливо якщо вони постачаються зовні у ваш код). Окрім зменшення ін'єкцій SQL, це також означає, що ваш код буде працювати правильно для нестандартних імен ідентифікаторів.

Ця функція підходить лише для імен об'єктів (наприклад, імена таблиці, стовпців, баз даних).

Вам слід спробувати параметризувати все інше та використовувати sp_executesql, передаючи параметри, а не об'єднуючи їх у рядок запиту.

Остаточною статтею на цю тему все ще є «Прокляття та благословення динамічного SQL»


Редагувати. Тепер ви надали код, я бачу, що він передає другий параметр, 'щоб додати зовнішні лапки та уникнути будь-яких цитат, подвоївши їх, перш ніж вводити їх у рядок. Це не дуже корисне використання лапки. Він вийде з ладу (поверне нуль), якщо рядок перевищує 128 символів.

Крім того, він все ще може залишити можливості ін'єкції SQL, якщо рядок містить U + 02BC замість стандартного апострофа, а потім рядок після санації призначається варчару ( де він може мовчки перетворитися на звичайний апостроф )

Правильний спосіб зробити це - залишити запит параметризованим. А потім передайте @parm1значення вsys.sp_executesql

DECLARE @Sql NVARCHAR(MAX);

SET @Sql = '
SELECT project      [Project],
       project_desc [Description],
       customer     [Customer],
       cpnyid       [Company]
FROM   PJPROJ (nolock)
WHERE  project LIKE @parm1 
';

EXEC sys.sp_executesql
  @Sql,
  N'@parm1 varchar(100)',
  @parm1 = 'foobar%'; 
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.