0

我有一个存储过程,它正在生成一个将调用 EXECUTE() 的字符串。该字符串包含一个 UPDATE 语句。但是,它正在执行的列和值事先是未知的。这些通过 XML 字符串进入存储过程。然后,我使用 XML 查询将数据取出并放入临时表中。

这不是在清理数据。

DECLARE @TBL_FLD TABLE (
    TBL         VARCHAR(MAX),
    COL         VARCHAR(MAX),
    VAL         VARCHAR(MAX)
);

-- Fill @TBL_FLD via xml parsing (omitted for brevity)

DECLARE TBL_CURSOR CURSOR FOR
SELECT distinct (TBL) FROM @TBL_FLD;

OPEN TBL_CURSOR;
WHILE 1 = 1
BEGIN
    FETCH NEXT FROM TBL_CURSOR INTO @TABLE_NAME
    IF ( @@FETCH_STATUS <> 0 )
        BREAK

    SET @SETTING_STR = '';
    SELECT @SETTING_STR = STUFF( ( SELECT ', ' + COL + ' = ''' + VAL + '''' FROM @TBL_FLD WHERE TBL = @TABLE_NAME FOR XML PATH('') ), 1, 2, '');

    SET @SQL_QUERY += 'UPDATE ' + @TABLE_NAME + ' SET ' + @SETTING_STR + ' WHERE KEY = ' + CONVERT(VARCHAR(MAX), @KEY_VAL) + '; ';

END
CLOSE TBL_CURSOR
DEALLOCATE TBL_CURSOR

EXECUTE (@SQL_QUERY);

我相信 @TBL_FLD 的 COL 字段,但 VAL 将来自用户。这留下了一个巨大的安全漏洞,因为我只是将数据连接在一起。一定有更好的方法。

由于列数未知,我无法轻松地为语句创建参数以便清理数据。如果最坏的情况发生,我可以做到,(请参阅在存储过程中动态创建更新 SQL的答案)但它会比我想要的更难看。

在我盲目地将数据添加到语句之前,是否有一种功能或方法来清理数据?还是有更好的方法来做我想做的事情?

4

1 回答 1

1

我认为只需将单引号与REPLACEVAL 加倍就可以解决任何问题,因为攻击者将无法退出“字符串范围”来执行任意代码:

SELECT @SETTING_STR = STUFF( ( SELECT ', ' + COL + ' = ''' + REPLACE(VAL, '''', '''''') + '''' FROM @TBL_FLD WHERE TBL = @TABLE_NAME FOR XML PATH('') ), 1, 2, '');

我不记得做同样事情的内置 T-SQL 函数

于 2013-06-20T01:56:06.717 回答