7

議論のために、INSERT を持つ SQL クエリを含むローカル変数を作成する必要があるとしましょう。

 DECLARE @insert NVARCHAR(MAX)
 SELECT @insert = 'INSERT INTO [dbo].[' + @table + '] VALUES...
 EXEC (@insert) 

この INSERT には、列の値も含まれます。

 DECLARE @insert NVARCHAR(MAX)
 SELECT @insert = 
  'INSERT INTO [dbo].[' + @table + '] VALUES (N''' + @message + ''')'
 EXEC (@insert) 

さて、私は明らかにインジェクション攻撃を懸念しており、@message の値によって @insert の値が悪意のあるものや、EXEC へのクエリとして不正な形式にならないようにしたいと考えています。

これは私の質問につながります: @message の ' 文字をエスケープするだけで十分ですか? @message に表示され、エスケープできる他の文字はありますか?

例:

 DECLARE @insert NVARCHAR(MAX)
 SELECT @message = REPLACE(@message,'''','''''')
 SELECT @insert = 
  'INSERT INTO [dbo].[' + @table + '] VALUES (N''' + @message + ''')'
 EXEC (@insert)  

(私が「する必要がある」と言うときこれはクエリがストアド プロシージャにあり、このストアド プロシージャが INSERT 先のテーブルである @table を受け入れるためです。自分のアーキテクチャや、なぜテーブルがto INSERT into は、プロシージャ パラメータを介して「動的に」指定されます。テーブル名をプロシージャ パラメータとして受け取ったときに、INSERT 先のテーブルを指定するクエリを EXEC() する以外に別の方法がない限り、これについてコメントすることは控えてください。)

4

5 に答える 5

10

sp_executesqlと組み込みのquotename(). この記事The Curse and Blessings of Dynamic SQLは、ほとんど決定的なリファレンスです。

于 2009-04-01T02:40:24.347 に答える
2

最初に通常の T-SQL を使用してスキーマ情報をクエリし、最初にテーブル名が存在することを確認します。このように、不正な SQL の場合、コードとして実行されません。単なる VARCHAR テーブル名になります。

DECLARE @Table AS VARCHAR(MAX)
DECLARE @Exists AS BIT

SET @Table = 'Vicious malformed dynamic SQL'

SELECT  @Exists = COUNT(TABLE_NAME) 
FROM    INFORMATION_SCHEMA.TABLES 
WHERE   TABLE_NAME = @Table

IF (@Exists = 1)
    BEGIN
    PRINT 'Table exists'
    -- Execute dynamic SQL.
    END
ELSE
    PRINT 'Invalid table'

(または単に IF EXISTS (SELECT ....) を使用します)

于 2009-04-01T03:05:40.057 に答える
2

EXEC(@somesql) を呼び出すのではなく、sp_executesql ストアド プロシージャを使用することをお勧めします。具体的には、これによりパラメーターを渡すことができ、システムはパラメーターが有効であることを確認します。

于 2009-04-01T02:42:39.363 に答える
0

私のテストによると、2008年でも、SQL識別子が必要なため、quotename()には128の長さの制限があるようです。リファレンスでは、次と同じことを行うquotestring()関数を作成することを提案しています。

REPLACE(@variable,'''','''''')

したがって、答えは上記の REPLACE() から次のように関数を作成することであると提案しています。

CREATE FUNCTION quotestring(@string nvarchar(MAX)) 
RETURNS nvarchar(MAX) AS
BEGIN
    RETURN(REPLACE(@string,'''',''''''))
END

...私が何かを誤解していない限り。

于 2009-04-01T16:07:44.237 に答える