recherche

Maison  >  Questions et réponses  >  le corps du texte

Quel est le moyen de protéger cette fonction de l’injection SQL ?

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

P粉573943755P粉573943755479 Il y a quelques jours816

répondre à tous(2)je répondrai

  • P粉434996845

    P粉4349968452023-11-08 20:39:55

    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

    répondre
    0
  • P粉738346380

    P粉7383463802023-11-08 09:41:58

    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 !

    répondre
    0
  • Annulerrépondre