我熟悉QUOTENAME函数。但我不明白我可以使用它?为什么它被广泛使用?为什么我们应该使用QUOTENAME函数?
select quotename('[abc]') -- '[[abc]]]'
select quotename('abc') -- '[abc]'
select '[' + 'abc' +']' -- why it is not so good as previous?
我熟悉QUOTENAME函数。但我不明白我可以使用它?为什么它被广泛使用?为什么我们应该使用QUOTENAME函数?
select quotename('[abc]') -- '[[abc]]]'
select quotename('abc') -- '[abc]'
select '[' + 'abc' +']' -- why it is not so good as previous?
想象一下,定期运行以下脚本以清除除dbo
架构以外的架构中的表。
DECLARE @TABLE_SCHEMA SYSNAME,
@TABLE_NAME SYSNAME
DECLARE @C1 AS CURSOR;
SET @C1 = CURSOR FAST_FORWARD
FOR SELECT TABLE_SCHEMA,
TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA <> 'dbo'
OPEN @C1;
FETCH NEXT FROM @C1 INTO @TABLE_SCHEMA, @TABLE_NAME;
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'DROP TABLE [' + @TABLE_SCHEMA + '].[' + @TABLE_NAME + ']';
EXEC ('DROP TABLE [' + @TABLE_SCHEMA + '].[' + @TABLE_NAME + ']');
FETCH NEXT FROM @C1 INTO @TABLE_SCHEMA, @TABLE_NAME;
END
如果您创建以下并运行该脚本,则尽管使用手动字符串连接方法,但仍然按预期工作。表foo.bar
被删除。
CREATE SCHEMA foo
CREATE TABLE foo.bar(x int)
现在创建以下,并尝试
CREATE TABLE foo.[[abc]]](x int)
脚本失败
DROP TABLE [foo].[[abc]]
Msg 105, Level 15, State 1, Line 6
Unclosed quotation mark after the character string '[abc]'.
Msg 102, Level 15, State 1, Line 6
Incorrect syntax near '[abc]'.
所以不使用QUOTENAME
已引起脚本失败的错误。将右括号加倍不能正确逃脱。正确的语法应该是
DROP TABLE [foo].[[abc]]]
更糟糕的消息是恶意开发者已经知道脚本的存在。它们在脚本计划运行之前执行以下操作。
CREATE TABLE [User supplied name]];
EXEC sp_addsrvrolemember 'SomeDomain\user2216', 'sysadmin'; --]
(
x int
)
现在正在执行的最终剧本
DROP TABLE [foo].[User supplied name];
EXEC sp_addsrvrolemember 'SomeDomain\user2216', 'sysadmin'; --]
的]
被解读为封闭的对象名,其余为新的声明。第一条语句返回一条错误消息,但不是一个范围终止,第二条仍然执行。通过不使用QUOTENAME
你已经打开了自己的SQL注入和开发人员已成功地升级其权限
QUOTENAME
可以在生成动态SQL语句时使用。它确实会将您的列名置于括号之间,但也会转义会破坏您引用的列名称并可能导致SQL注入的字符。
例如:
SELECT QUOTENAME('abc[]def');
返回结果:
[abc[]]def]
欲了解更多信息:QUOTENAME (MSDN)
请您提供有关如何防止注入更多的细节? – user2216
如果你在用户输入字符串周围使用QUOTENAME,这样的事情不是问题。选择QUOTENAME('或1 = 1; truncate table Users') –
@ user2216 - 添加示例 –