Mysql
 sql >> база данни >  >> RDS >> Mysql

SQL SERVER – Един трик за боравене с динамичен SQL за избягване на атака с инжектиране на SQL?

SQL Server има толкова много неща за научаване и винаги го намирам за невероятно. В разговорите ми с клиенти често се появяват въпроси за сигурност, особено около SQL инжектирането. Мнозина твърдят, че SQL инжектирането е проблем на SQL Server. Отнема доста време, за да ги уведомя, че няма нищо за SQL Server и SQL Injection. SQL инжекцията е резултат от грешни практики за кодиране. Една от препоръките, които давам, е да не използвате Dynamic SQL. Може да има някои ситуации, в които не можете да го избегнете. Единственият ми съвет би бил, избягвайте, ако е възможно. В този блог ще демонстрирам проблем с инжектирането на SQL поради динамичен SQL и възможно решение, което можете да имате.

Да предположим, че имаме проста страница за търсене, където потребителят може да използва празното търсене или да предостави филтър във всяко поле. Предоставихме две полета за използване на „Име“ и „Фамилия“. Потребителят въвежда нещо и натиска търсене. Ето нашия код на съхранена процедура, който се задейства зад сцената.

USE AdventureWorks2014
GO
CREATE PROCEDURE search_first_or_last
@firstName NVARCHAR(50)
,@lastName NVARCHAR(50)
AS
BEGIN
DECLARE @sql NVARCHAR(4000)
SELECT @sql = ' SELECT FirstName ,MiddleName, LastName' +
' FROM Person.Person WHERE 1 = 1 '
IF @firstName IS NOT NULL
SELECT @sql = @sql + ' AND FirstName LIKE ''' + @firstName + ''''
IF @lastName IS NOT NULL
SELECT @sql = @sql + ' AND LastName LIKE ''' + @lastName + ''''
EXEC (@sql)
END

Ако използвам този низ за изпълнение на фамилно име ”;пуснете таблица t1–

EXEC search_first_or_last '%K%', ''';drop table t1--'

Динамичният низ ще бъде

SELECT FirstName, MiddleName, LastName FROM Person.
Person WHERE 1 = 1 AND FirstName LIKE '%K%' AND LastName LIKE '';DROP TABLE t1--'

Виждате ли проблема? Да, потребителите могат да хвърлят таблица t1, ако кодът се изпълнява под акаунт с високи привилегии.

Едно от решенията на проблема би било използването на sp_executesql. Ето по-добрата версия с

CREATE PROCEDURE search_first_or_last
@firstName NVARCHAR(50)
,@lastName NVARCHAR(50)
AS
BEGIN
DECLARE @sql NVARCHAR(4000)
SELECT @sql = ' SELECT FirstName , MiddleName, LastName' +
' FROM Person.Person WHERE 1 = 1 '
IF @firstName IS NOT NULL
SELECT @sql = @sql + ' AND FirstName LIKE @firstName'
IF @lastName IS NOT NULL
SELECT @sql = @sql + ' AND LastName LIKE @lastName '
EXEC sp_executesql @sql
,N'@firstName nvarchar(50), @lastName nvarchar(50)'
,@firstName
,@lastName
END

Надявам се, че ще можете да използвате това и да приложите във вашия проект. Използвате ли тези прости техники във вашия производствен код? Сблъсквали ли сте се някога с подобни проблеми по време на одит? Уведомете ме за вашите знания.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Отдалечената връзка с MySQL се проваля с неизвестен метод за удостоверяване

  2. Мигриране на база данни на Oracle към MySQL на AWS, част 1

  3. Как да наблюдавате множество MySQL екземпляри, работещи на една и съща машина - ClusterControl Съвети и трикове

  4. YEARWEEK() Примери – MySQL

  5. Как да зададете набора от символи и съпоставяне на база данни в MySQL