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

Autoriser un utilisateur à transmettre le nom de la table et le nom de la colonne tout en empêchant l'injection SQL

C'est ce que QUOTENAME() a été créé pour résoudre. Vous transmettez vos noms de colonne et de table en tant que paramètres dans QUOTENAME() puis vous en utilisez la sortie pour représenter les objets de votre base de données dans une requête sql dynamique.

//The evil name tries to expliot code like:
//  set @sql = N'CREATE TABLE [' + @tablename + N'] (Foo int)'
var evilName = "someName] (Foo int); Drop table students --";

var query = @"
declare @sql as nvarchar(max)
set @sql = N'CREATE TABLE ' + QUOTENAME(@tablename) + N' (Foo int)'
exec sp_executesql @sql
";
using(var connection = new SqlConnection(ConnectionString))
using(var command = new SqlCommand(query, connection))
{
    command.Parameters.Add("@tablename", SqlDbType.NVarChar, 128).Value = evilName ;
    connection.Open();
    command.ExecuteNonQuery();
}

La requête qui sera exécutée sur le serveur sera

CREATE TABLE [someName]] (Foo int); Drop table students --] (Foo int)

qui crée une table avec un nom de table valide et ne supprime pas mon autre table.