Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Injections SQL avec remplacement des guillemets simples et validation des entiers

S'il s'agit d'un projet hérité qui est codé de cette manière, alors, même s'il n'est pas optimal, je ne suis actuellement pas au courant qu'il puisse être sensible à l'injection SQL tant que chaque chaîne est traitée de cette manière et que les requêtes sont simplement simples ceux que vous avez montrés.

Je ne peux cependant pas affirmer plus de certitude que cela. Sans utiliser de requêtes paramétrées, il y a toujours la possibilité qu'il y ait une vulnérabilité que vous n'avez pas encore prise en compte.

Échapper manuellement les guillemets vous-même est sujet aux erreurs et peut parfois échouer de manière difficile à anticiper à l'avance. Par exemple avec le tableau suivant

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

Et procédure stockée utilisant SQL dynamique construit avec concaténation de chaînes

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)

Vous pouvez essayer ce qui suit

Mise à jour normale

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

Tentative d'injection SQL déjouée

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

La tentative d'injection SQL réussit et supprime la table

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

Le problème ici est que la troisième requête passe U+02BC au lieu de l'apostrophe standard, puis la chaîne est affectée à un varchar(max) après l'assainissement qui le convertit silencieusement en une apostrophe régulière.

Jusqu'à ce que je lise la réponse ici ce problème ne me serait jamais venu à l'esprit.