2011-01-12 5 views
2

J'ai une procédure stockée qui prend le nom d'une table en tant que paramètre et utilise SQL dynamique pour effectuer la sélection. J'ai essayé de passer @TableName en tant que paramètre et d'utiliser sp_executesql mais cela a généré une erreur. J'ai décidé d'aller avec SQL dynamique directement sans utiliser sp_executesql.Comment sécuriser une procédure stockée SQL dynamique?

Y at-il autre chose que je devrais faire pour sécuriser le paramètre @TableName pour éviter les attaques par injection SQL?

procédure stockée ci-dessous:

CREATE PROCEDURE dbo.SP_GetRecords 
    ( 
    @TableName VARCHAR(128) = NULL 
    ) 
AS 
BEGIN 

    /* Secure the @TableName Parameter */   
    SET @TableName = REPLACE(@TableName, ' ','')  
    SET @TableName = REPLACE(@TableName, ';','')  
    SET @TableName = REPLACE(@TableName, '''','') 

    DECLARE @query NVARCHAR(MAX)  

    /* Validation */  
    IF @TableName IS NULL 
    BEGIN  
     RETURN -1 
    END 

    SET @query = 'SELECT * FROM ' + @TableName 
    EXEC(@query)   
END 

Cela a échoué lors de l'utilisation sp_executesql à la place:

SET @query = 'SELECT * FROM @TableName' 
EXEC sp_executesql @query, N'@TableName VARCHAR(128)', @TableName 

ERROR: Must declare the table variable "@TableName".

+1

Quelle que soit la solution que vous choisissez, sachez que lorsque vous exécutez SQL dynamique dans une procédure stockée, que SQL exécute par défaut avec les autorisations de l'appelant proc * stocké *. Considérant que SQL normal dans une procédure stockée s'exécute par défaut avec les autorisations du proc * propriétaire * stocké. – RoadWarrior

Répondre

2

vous bien sûr peut regarder la table sysobjects et veiller à ce qu'il existe

Select id from sysobjects where xType = 'U' and [name] = @TableName 

En outre (Exemple plus complet):

DECLARE @TableName nVarChar(255) 
DECLARE @Query nVarChar(512) 

SET @TableName = 'YourTable' 
SET @Query = 'Select * from ' + @TableName 

-- Check if @TableName is valid 
IF NOT (Select id from sysobjects where xType = 'U' and [name] = @TableName) IS NULL 
    exec(@Query) 
+0

La chaîne non sécurisée ne serait-elle pas incluse dans la requête pour vérifier l'existence des tables? –

+4

@jms mais ici vous pouvez utiliser les paramètres de liaison –

+0

@Markus convenu. –

Questions connexes