Quel est le moyen de protéger cette fonction de l'injection SQL ?
P粉573943755
P粉573943755 2023-11-07 22:03:43
0
2
737

public static bool TruncateTable(string dbAlias, string tableName)
{
    string sqlStatement = string.Format("TRUNCATE TABLE {0}", tableName);
    return ExecuteNonQuery(dbAlias, sqlStatement) > 0;
}

P粉573943755
P粉573943755

répondre à tous(2)
P粉434996845

Pour autant que je sache, vous ne pouvez pas utiliser de requêtes paramétrées pour exécuter des instructions DDL/spécifier des noms de table, du moins pas dans Oracle ou Sql Server. Si je devais avoir une fonction TruncateTable folle et pouvoir éviter l'injection SQL, alors ce que je ferais serait de créer une procédure stockée qui vérifie si l'entrée est une table qui peut être tronquée en toute sécurité.

-- Sql Server specific!
CREATE TABLE TruncableTables (TableName varchar(50))
Insert into TruncableTables values ('MyTable')

go

CREATE PROCEDURE MyTrunc @tableName varchar(50)
AS
BEGIN

declare @IsValidTable int
declare @SqlString nvarchar(50)
select @IsValidTable = Count(*) from TruncableTables where TableName = @tableName

if @IsValidTable > 0
begin
 select @SqlString = 'truncate table ' + @tableName
 EXECUTE sp_executesql @SqlString
end
END
P粉738346380

Le conseil le plus courant pour lutter contre l'injection SQL est d'utiliser les paramètres de requête SQL (plusieurs personnes sur ce fil ont suggéré de le faire).

Ce n'est pas la bonne réponse dans ce cas. Vous ne pouvez pas utiliser de paramètres de requête SQL sur les noms de table dans les instructions DDL.

Les paramètres de requête SQL ne peuvent être utilisés qu'à la place des valeurs littérales dans les expressions SQL. C'est la norme pour chaque implémentation SQL.

Lorsque vous avez des noms de table, ma recommandation pour empêcher l'injection SQL est de valider la chaîne d'entrée par rapport à une liste de noms de table connus.

Vous pouvez obtenir une liste de noms de tables valides à partir du INFORMATION_SCHEMA :

SELECT table_name 
FROM INFORMATION_SCHEMA.Tables 
WHERE table_type = 'BASE TABLE'
  AND table_name = @tableName

Vous pouvez désormais transmettre des variables d'entrée en tant que paramètres SQL à cette requête. Si la requête ne renvoie aucune ligne, vous savez que l'entrée n'est pas valide et ne peut pas être utilisée comme table. Si la requête renvoie une ligne, elle correspond, vous pouvez donc l'utiliser avec plus de confiance.

Vous pouvez également valider les noms de tables par rapport à une liste spécifique de tables que vous définissez comme disponibles pour que l'application les tronque, comme @John Buchanan suggéré.

Même après avoir vérifié que tableName existe en tant que nom de table dans votre SGBDR, je suggérerais également de délimiter le nom de la table, juste au cas où vous utiliseriez des noms de table avec des espaces ou des caractères spéciaux. Dans Microsoft SQL Server, les délimiteurs d'identifiant par défaut sont des crochets :

string sqlStatement = string.Format("TRUNCATE TABLE [{0}]", tableName);

Maintenant, vous ne risquez une injection SQL que si tableName correspond à une vraie table et que vous utilisez réellement des crochets dans les noms de vos tables !

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal