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

Iniezioni SQL con sostituzione di virgolette singole e convalida di interi

Se si tratta di un progetto legacy codificato in questo modo, sebbene non sia ottimale, al momento non sono a conoscenza di alcun modo in cui possa essere suscettibile all'iniezione SQL purché ogni stringa venga trattata in quel modo e le query siano semplicemente semplici quelli come hai mostrato.

Tuttavia, non posso affermare più certezza di questo. Senza utilizzare query parametrizzate c'è sempre la possibilità che ci sia qualche vulnerabilità che non hai ancora considerato.

L'elusione manuale delle virgolette da soli è soggetta a errori e talvolta può fallire in modi difficili da prevedere in anticipo. Ad esempio con la seguente tabella

CREATE TABLE myTable(title VARCHAR(100))
INSERT INTO myTable VALUES('Foo')

E stored procedure utilizzando SQL dinamico creato con concatenazione di stringhe

CREATE PROC UpdateMyTable
@newtitle NVARCHAR(100)
AS
/*
Double up any single quotes
*/
SET @newtitle = REPLACE(@newtitle, '''','''''')

DECLARE @UpdateStatement VARCHAR(MAX)

SET @UpdateStatement = 'UPDATE myTable SET title='''  + @newtitle + ''''

EXEC(@UpdateStatement)

Puoi provare quanto segue

Aggiornamento normale

EXEC UpdateMyTable N'Foo'
SELECT * FROM myTable /*Returns "Foo"*/

Tentativo di SQL injection sventato

EXEC UpdateMyTable N''';DROP TABLE myTable--'
SELECT * FROM myTable  /*Returns "';DROP TABLE myTable--"*/

Il tentativo di SQL injection riesce e elimina la tabella

EXEC UpdateMyTable N'ʼ;DROP TABLE myTable--'
SELECT * FROM myTable  /*Returns "Invalid object name 'myTable'."*/

Il problema qui è che la terza query supera U+02BC invece dell'apostrofo standard e quindi la stringa viene assegnata a un varchar(max) dopo che si verifica la sanificazione che lo converte silenziosamente in un apostrofo regolare.

Fino a quando non ho letto la risposta qui quel problema non mi sarebbe mai venuto in mente.