SQL Server har så mange ting at lære, og jeg synes altid, det er fantastisk. Mine samtaler med kunder kommer ofte med sikkerhedsspørgsmål, især omkring SQL Injection. Mange har hævdet, at SQL Injection er et SQL Server-problem. Det tager ret lang tid for mig at fortælle dem, at der ikke er noget om SQL Server og SQL Injection. SQL Injection er et resultat af forkert kodningspraksis. En af de anbefalinger, jeg giver, handler om ikke at bruge Dynamic SQL. Der kan være nogle situationer, hvor du ikke kan undgå det. Mit eneste råd ville være, undgå, hvis det er muligt. I denne blog vil jeg demonstrere et SQL Injection problem på grund af dynamisk SQL og en mulig løsning du kan have.
Lad os antage, at vi har en simpel søgeside, hvor brugeren kan bruge den tomme søgning eller angive filter i ethvert felt. Vi har angivet to felter til at bruge "Fornavn" og "Efternavn". Brugeren skriver noget og trykker på søg. Her er vores kode for lagret procedure, som skyder bag scenen.
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
Hvis jeg bruger denne streng til at udføre i efternavn "; drop tabel t1–
EXEC search_first_or_last '%K%', ''';drop table t1--'
Den dynamiske streng ville være
SELECT FirstName, MiddleName, LastName FROM Person. Person WHERE 1 = 1 AND FirstName LIKE '%K%' AND LastName LIKE '';DROP TABLE t1--'
Ser du problemet? Ja, brugere kan droppe tabel t1, hvis koden kører under en konto med højt privilegium.
En af løsningerne på problemet ville være at bruge sp_executesql. Her er den bedre version med
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
Håber du ville være i stand til at bruge dette og implementere i dit projekt. Bruger du disse enkle teknikker i din produktionskode? Har du nogensinde stået over for lignende problemer under revisionen? Fortæl mig om dine erfaringer.