我有一个存储过程正在生成一个它将调用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将来自用户。由于我只是将数据连接在一起,因此留下了巨大的安全漏洞。必须有更好的方法。
由于列数未知,我无法轻松为语句创建参数,以便清理数据。如果最坏的情况发生,我可以做到,(见Dynamically Create Update SQL In Stored Procedure的答案),但它会比我想要的更糟糕。
在我盲目地将其添加到声明之前,是否有一个函数或方法来清理数据?或者有更好的方法来做我想做的事情吗?
答案 0 :(得分:1)
我认为在VAL上使用REPLACE
加倍单引号会解决任何问题,因为攻击者无法退出“字符串作用域”来执行任意代码:
SELECT @SETTING_STR = STUFF( ( SELECT ', ' + COL + ' = ''' + REPLACE(VAL, '''', '''''') + '''' FROM @TBL_FLD WHERE TBL = @TABLE_NAME FOR XML PATH('') ), 1, 2, '');
我不记得内置的T-SQL函数做同样的事情