2011-01-12 1 views
2

私は、テーブルの名前をパラメータとしてとり、動的SQLを使用して選択を実行するストアドプロシージャを持っています。 @TableNameをパラメータとして渡してsp_executesqlを使用しようとしましたが、エラーが発生しました。私は、sp_executesqlを使用せずに直接動的SQLを使用することに決めました。動的SQLストアドプロシージャを保護する方法は?

SQLインジェクション攻撃を避けるために@TableNameパラメータを保護するために何かすべきことはありますか?

以下

ストアド・プロシージャの代わりにsp_executesqlを使用している場合

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 

は、これは失敗しました:

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

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

+1

を選択したどちらのソリューション、SQLが許可でデフォルトで実行されることを、あなたはストアドプロシージャ内の動的SQLを実行するときがあることに注意してください格納されたproc *呼び出し元の*。ストアドプロシージャ内の通常のSQLは、デフォルトではストアドproc * owner *の権限で実行されます。 – RoadWarrior

答えて

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) 
+0

テーブルの存在を確認するために、まだ安全でない文字列がクエリに含まれていませんか? –

+4

@jmsしかしここではバインドパラメータを使うことができます –

+0

@Markus agree。 –

関連する問題