SQL Server má tolik věcí, které se lze naučit, a vždy mi to přijde úžasné. Moje rozhovory se zákazníky často přicházejí s bezpečnostními otázkami, zejména kolem SQL Injection. Mnozí tvrdili, že SQL Injection je problém se serverem SQL. Nějakou dobu mi trvá, než jim dám vědět, že o SQL Server a SQL Injection nic není. SQL Injection je výsledkem nesprávných postupů kódování. Jedno z doporučení, které uvádím, je nepoužívat dynamické SQL. Mohou nastat situace, kdy se tomu nevyhnete. Moje jediná rada by byla, vyhněte se, pokud je to možné. V tomto blogu bych předvedl problém vkládání SQL kvůli dynamickému SQL a možné řešení, které můžete mít.
Předpokládejme, že máme jednoduchou vyhledávací stránku, kde může uživatel použít prázdné vyhledávání nebo zadat filtr v libovolném poli. Poskytli jsme dvě pole pro použití „Jméno“ a „Příjmení“. Uživatel něco zadá a stiskne vyhledávání. Zde je náš kód uložené procedury, která se spustí za scénou.
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
Pokud tento řetězec použiji k provedení v příjmení ”;drop table t1–
EXEC search_first_or_last '%K%', ''';drop table t1--'
Dynamický řetězec by byl
SELECT FirstName, MiddleName, LastName FROM Person. Person WHERE 1 = 1 AND FirstName LIKE '%K%' AND LastName LIKE '';DROP TABLE t1--'
Vidíte problém? Ano, uživatelé mohou zrušit tabulku t1, pokud kód běží pod účtem s vysokým oprávněním.
Jedním z řešení problému by bylo použití sp_executesql. Zde je lepší verze pomocí
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
Doufám, že to budete moci využít a implementovat do svého projektu. Používáte tyto jednoduché techniky ve svém produkčním kódu? Setkali jste se někdy s podobnými problémy během auditu? Dejte mi vědět o svých poznatcích.