小编Ros*_*ury的帖子

在不使用QUOTENAME的情况下,在SQL Server中正确转义分隔标识符

代码必须做些什么来清理标识符(表,视图,列),而不是用双引号将它们包装起来,并在标识符名称中出现"double up"双引号? 参考文献将不胜感激.

我继承了一个具有自定义对象关系映射(ORM)系统的代码库.SQL无法在应用程序中编写,但ORM仍必须最终生成要发送到SQL Server的SQL.所有标识符都用双引号引用.

string QuoteName(string identifier) 
{ 
    return "\"" + identifier.Replace("\"", "\"\"") + "\"";
}
Run Code Online (Sandbox Code Playgroud)

如果我在SQL中构建这个动态SQL ,我会使用内置的SQL Server QUOTENAME函数:

declare @identifier nvarchar(128);
set @identifier = N'Client"; DROP TABLE [dbo].Client; --';

declare @delimitedIdentifier nvarchar(258);
set @delimitedIdentifier = QUOTENAME(@identifier, '"');

print @delimitedIdentifier;
-- "Client""; DROP TABLE [dbo].Client; --"
Run Code Online (Sandbox Code Playgroud)

我还没有找到任何关于如何在SQL Server中转义带引号的标识符的权威文档.我找到了分隔标识符(数据库引擎),我也看到了关于清理的这个stackoverflow问题.

如果必须调用QUOTENAME函数只是为了引用那些不需要SQL Server的大量流量的标识符.

关于SQL注入,ORM似乎已经过深思熟虑了.它位于C#中,早于nHibernate端口和E​​ntity Framework等.所有用户输入都是使用ADO.NET SqlParameter对象发送的,它只是我在这个问题中关注的标识符名称.这需要适用于SQL Server 2005和2008.


2010-03-31更新

虽然应用程序不允许在查询中允许用户输入标识符名称,但ORM通过它对ORM样式读取和自定义查询具有的查询语法来执行.正是我试图最终阻止所有可能的SQL注入攻击的ORM,因为它非常小并且易于验证而不是所有应用程序代码.

查询界面的一个简单示例:

session.Query(new TableReference("Client")
    .Restrict(new FieldReference("city") == "Springfield")
    .DropAllBut(new FieldReference("first_name"));
Run Code Online (Sandbox Code Playgroud)

ADO.NET发送此查询:

exec sp_executesql N'SELECT "T1"."first_name" 
FROM …
Run Code Online (Sandbox Code Playgroud)

t-sql sql-server sql-injection sql-server-2005 sql-server-2008

9
推荐指数
1
解决办法
8387
查看次数