SQL Server ha così tante cose da imparare e lo trovo sempre sorprendente. Le mie conversazioni con i clienti spesso emergono con domande di sicurezza in particolare su SQL Injection. Molti hanno affermato che SQL injection è un problema di SQL Server. Mi ci vuole un po' di tempo per far loro sapere che non c'è nulla in SQL Server e SQL Injection. SQL injection è il risultato di pratiche di codifica sbagliate. Uno dei consigli che do riguarda il non utilizzare Dynamic SQL. Potrebbero esserci alcune situazioni in cui non puoi evitarlo. Il mio unico consiglio sarebbe, se possibile, evitarlo. In questo blog, mostrerei un problema di SQL Injection dovuto all'SQL dinamico e una possibile soluzione che puoi avere.
Supponiamo di avere una semplice pagina di ricerca in cui l'utente può utilizzare la ricerca vuota o fornire un filtro in qualsiasi campo. Abbiamo fornito due campi per utilizzare "Nome" e "Cognome". L'utente digita qualcosa e preme la ricerca. Ecco il nostro codice di procedura memorizzata che si attiva dietro le quinte.
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
Se uso questa stringa per eseguire nel cognome ”;rilascia la tabella t1–
EXEC search_first_or_last '%K%', ''';drop table t1--'
La stringa dinamica sarebbe
SELECT FirstName, MiddleName, LastName FROM Person. Person WHERE 1 = 1 AND FirstName LIKE '%K%' AND LastName LIKE '';DROP TABLE t1--'
Vedi il problema? Sì, gli utenti possono eliminare la tabella t1 se il codice è in esecuzione con un account con privilegi elevati.
Una delle soluzioni del problema sarebbe usare sp_executesql. Ecco la versione migliore utilizzando
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
Spero che tu possa usarlo e implementarlo nel tuo progetto. Stai usando queste semplici tecniche nel tuo codice di produzione? Hai mai affrontato problemi simili durante l'audit? Fammi sapere dei tuoi insegnamenti.