Dovremmo ancora usare QUOTENAME per proteggerci dagli attacchi di iniezione?


9

Oggi stavo guardando una vecchia procedura memorizzata e ho notato che stava usando quotenamei parametri di input. Dopo aver fatto qualche scavo per capire cosa fa esattamente mi sono imbattuto in questo sito . Ora capisco cosa fa e come usarlo, ma il sito dice che viene utilizzato come mitigazione dagli attacchi SQL Injection. Quando ero abituato a sviluppare app che richiedevano direttamente un database, usando asp.net, utilizzavo i parametri ADO.Net per trasmettere l'input dell'utente come valore letterale e non mi preoccupavo davvero di proteggerlo nelle mie procedure memorizzate.

Ora sto scrivendo una procedura memorizzata che verrà utilizzata dalle applicazioni che non scrivo, quindi ho bisogno di provare a proteggere dagli attacchi di iniezione a livello di procedura, è il quotenamemodo migliore per farlo o c'è una nuova funzione / migliore metodo?

Codice che mi ha portato su questo modello di pensiero ( @parm1è un parametro di input dell'utente):

'SELECT project [Project], project_desc [Description], 
        customer [Customer], cpnyid [Company]
FROM PJPROJ (nolock)
where project like ' + quotename(@parm1,'''') + '

Risposte:


17

Sì, le cose non sono cambiate molto in quest'area, dovresti usare quotenameper qualsiasi nome di oggetto del server SQL utilizzato in SQL dinamico (specialmente se fornito esternamente al tuo codice). Oltre alla mitigazione dell'iniezione SQL, ciò significa anche che il codice funzionerà correttamente per i nomi di identificatori non standard.

La funzione è appropriata solo per i nomi degli oggetti (ad es. Tabella, colonna, nomi di database).

Dovresti provare a parametrizzare tutto il resto e usare sp_executesql, passando i parametri anziché concatenarli nella stringa di query.

L'articolo definitivo su questo argomento è ancora The Curse and Blessings of Dynamic SQL


Modificare. Ora hai fornito il codice, vedo che sta passando il secondo parametro 'per aggiungere le virgolette esterne e sfuggire alle virgolette singole raddoppiandole prima di iniettarle nella stringa. Questo non è un buon uso di quotename. Fallirà (restituisce null) se la stringa è maggiore di 128 caratteri.

Inoltre, può ancora lasciare possibilità di iniezione SQL se la stringa contiene U + 02BC invece dell'apostrofo standard e quindi la stringa viene assegnata a un varchar dopo il risanamento ( dove può essere silenziosamente convertita in un apostrofo normale )

Il modo corretto per farlo è lasciare la query parametrizzata. E poi passa il @parm1valore asys.sp_executesql

DECLARE @Sql NVARCHAR(MAX);

SET @Sql = '
SELECT project      [Project],
       project_desc [Description],
       customer     [Customer],
       cpnyid       [Company]
FROM   PJPROJ (nolock)
WHERE  project LIKE @parm1 
';

EXEC sys.sp_executesql
  @Sql,
  N'@parm1 varchar(100)',
  @parm1 = 'foobar%'; 
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.