我熟悉QUOTENAME功能.但我不明白我能用什么呢?为什么这么广泛使用?
select quotename('[abc]') -- '[[abc]]]'
select quotename('abc') -- '[abc]'
select '[' + 'abc' +']' -- why it is not so good as previous?
Run Code Online (Sandbox Code Playgroud)
想象一下,计划定期运行以下脚本来清理模式以外的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
Run Code Online (Sandbox Code Playgroud)
如果您创建以下内容并运行脚本,则尽管使用手动字符串连接方法,但所有操作都按预期工作.该表foo.bar已删除.
CREATE SCHEMA foo
CREATE TABLE foo.bar(x int)
Run Code Online (Sandbox Code Playgroud)
现在创建以下内容并尝试
CREATE TABLE foo.[[abc]]](x int)
Run Code Online (Sandbox Code Playgroud)
该脚本失败并显示错误
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]'.
Run Code Online (Sandbox Code Playgroud)
所以不使用QUOTENAME导致脚本失败.关闭括号没有通过加倍来正确逃脱.应该是正确的语法
DROP TABLE [foo].[[abc]]]
Run Code Online (Sandbox Code Playgroud)
更糟糕的是,恶意开发者已经了解了脚本的存在.它们在脚本计划运行之前执行以下操作.
CREATE TABLE [User supplied name]];
EXEC sp_addsrvrolemember 'SomeDomain\user2216', 'sysadmin'; --]
(
x int
)
Run Code Online (Sandbox Code Playgroud)
现在最终执行的脚本是
DROP TABLE [foo].[User supplied name];
EXEC sp_addsrvrolemember 'SomeDomain\user2216', 'sysadmin'; --]
Run Code Online (Sandbox Code Playgroud)
将]被解读为封闭的对象名,其余为新的声明.第一个语句返回一条错误消息,但没有一个范围终止一个,第二个语句仍然执行.通过不使用,QUOTENAME您已经打开了自己的SQL注入,开发人员已经成功升级了他们的权限