如何保护动态SQL存储过程?

时间:2011-01-12 17:30:18

标签: sql stored-procedures sql-injection dynamic-sql

我有一个存储过程,它将表的名称作为参数,并使用动态sql来执行select。我试图将@TableName作为参数传递并使用sp_executesql但是引发了错误。我决定使用直接动态sql而不使用sp_executesql。

我还有什么办法来保护@TableName参数以避免sql注入攻击吗?

以下存储过程:

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

使用sp_executesql时失败:

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

错误:必须声明表变量   “@tablename”。

2 个答案:

答案 0 :(得分:3)

答案 1 :(得分:2)

你当然可以查看sysobjects表并确保它存在

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

进一步(更完整的例子):

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)