Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Come pulire (impedire SQL injection) SQL dinamico in SQL Server?

Credo che ci siano tre diversi casi di cui devi preoccuparti:

  • stringhe (tutto ciò che richiede virgolette):'''' + replace(@string, '''', '''''') + ''''
  • nomi (tutto ciò in cui non sono consentite virgolette):quotename(@string)
  • cose che non possono essere citate:questo richiede la whitelist

Nota :Tutto in una variabile stringa (char , varchar , nchar , nvarchar , ecc.) che provenga da fonti controllate dall'utente devono utilizzare uno dei metodi sopra indicati. Ciò significa che anche le cose che ti aspetti siano numeri vengono citate se sono archiviate in variabili stringa.

Per maggiori dettagli, vedere Microsoft Magazine (Link obsoleto:19-10-2016) .

Ecco un esempio che utilizza tutti e tre i metodi:

EXEC 'SELECT * FROM Employee WHERE Salary > ''' +
     REPLACE(@salary, '''', '''''') +   -- replacing quotes even for numeric data
     ''' ORDER BY ' + QUOTENAME(@sort_col) + ' ' +  -- quoting a name
     CASE @sort_dir WHEN 'DESC' THEN 'DESC' END     -- whitelisting

Nota anche che eseguendo tutte le operazioni sulle stringhe in linea nel EXEC dichiarazione non vi è alcuna preoccupazione per i problemi di troncamento. Se assegni i risultati intermedi alle variabili, devi assicurati che le variabili siano abbastanza grandi da contenere i risultati. Se fai SET @result = QUOTENAME(@name) dovresti definire @result contenere almeno 258 (2 * 128 + 2) caratteri. Se lo fai SET @result = REPLACE(@str, '''', '''''') dovresti definire @result essere il doppio di @str (assume ogni carattere in @str potrebbe essere una citazione). E, naturalmente, la variabile stringa che contiene l'istruzione SQL finale deve essere abbastanza grande da contenere tutto l'SQL statico più tutte le variabili di risultato.