sql-server – 在不使用QUOTENAME的情况下,在SQL Server中正确转义分隔标识符
|
代码必须做些什么来清理标识符(表,视图,列),而不是用双引号将它们包装起来,并在标识符名称中出现“double up”双引号?参考文献将不胜感激. 我继承了一个具有自定义对象关系映射(ORM)系统的代码库. SQL无法在应用程序中编写,但ORM仍必须最终生成要发送到SQL Server的SQL.所有标识符都用双引号引用. string QuoteName(string identifier)
{
return """ + identifier.Replace(""","""") + """;
}
如果我在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; --" 我没有找到任何关于如何在SQL Server中转义带引号的标识符的权威文档.我找到了Delimited Identifiers (Database Engine),我也看到了this stackoverflow question关于消毒. 如果必须调用QUOTENAME函数只是为了引用那些不需要SQL Server的大量流量的标识符. 关于SQL注入,ORM似乎已经过深思熟虑了.它位于C#中,早于nHibernate端口和实体框架等.所有用户输入都是使用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"));
ADO.NET发送此查询: exec sp_executesql N'SELECT "T1"."first_name" FROM "dbo"."Client" AS "T1" WHERE "T1"."city" = @p1;',N'@p1 nvarchar(30)',N'Springfield'; 也许有必要考虑一下nHibernate查询语言(HQL)中的类似内容: using (ISession session = NHibernateHelper.OpenSession())
{
Client client = session
.CreateCriteria(typeof(Client)) <-- TableReference in example above
.Add(Restrictions.Eq("city","Springfield")) <-- FieldReference above
.UniqueResult<Client>();
return client;
}
也许我应该看看nHibernate如何保护输入. 解决方法您的QuoteName函数需要检查长度,因为T-SQL QUOTENAME函数指定它返回的最大长度.使用你的例子:String.Format(@"declare @delimitedIdentifier nvarchar(258);
set @delimitedIdentifier = {0};",QuoteName(identifier));
如果QuoteName(标识符)超过258个字符,则在分配给@delimitedIdentifier时将以静默方式截断它.当发生这种情况时,您可能会打开@delimitedIdentifier不正确转义的可能性. 微软的“安全软件开发人员”Bala Neerumalla有an MSDN article,它更深入地解释了这个主题.本文还包含了我发现的“关于如何在SQL Server中转义引用标识符的权威文档”中最接近的内容:
这是我目前使用的C#代码: /// <summary>
/// Returns a string with the delimiters added to make the input string
/// a valid SQL Server delimited identifier. Brackets are used as the
/// delimiter. Unlike the T-SQL version,an ArgumentException is thrown
/// instead of returning a null for invalid arguments.
/// </summary>
/// <param name="name">sysname,limited to 128 characters.</param>
/// <returns>An escaped identifier,no longer than 258 characters.</returns>
public static string QuoteName(string name) { return QuoteName(name,'['); }
/// <summary>
/// Returns a string with the delimiters added to make the input string
/// a valid SQL Server delimited identifier. Unlike the T-SQL version,/// an ArgumentException is thrown instead of returning a null for
/// invalid arguments.
/// </summary>
/// <param name="name">sysname,limited to 128 characters.</param>
/// <param name="quoteCharacter">Can be a single quotation mark ( ' ),a
/// left or right bracket ( [] ),or a double quotation mark ( " ).</param>
/// <returns>An escaped identifier,no longer than 258 characters.</returns>
public static string QuoteName(string name,char quoteCharacter) {
name = name ?? String.Empty;
const int sysnameLength = 128;
if (name.Length > sysnameLength) {
throw new ArgumentException(String.Format(
"name is longer than {0} characters",sysnameLength));
}
switch (quoteCharacter) {
case ''':
return String.Format("'{0}'",name.Replace("'","''"));
case '"':
return String.Format(""{0}"",name.Replace(""",""""));
case '[':
case ']':
return String.Format("[{0}]",name.Replace("]","]]"));
default:
throw new ArgumentException(
"quoteCharacter must be one of: ',",[,or ]");
}
} (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- SQL Server 2000数据库同步 同步两个SQLServer数据库的内容
- RODBC sqlQuery()在返回varchar(MAX)时返回varchar(255)
- .net – 连接字符串中的SQL Server Compact“数据目录”宏
- sql存储过程实例--动态根据表数据复制一个表的数据到另一个
- sql – 在什么条件下,SELECT by PRIMARY KEY会变慢?
- sql-server – 作为一名DBA,我将如何从Oracle转换到SQL Ser
- sql – 如何停止EF(代码优先)检查架构更改
- sql – SSIS时间戳
- hibernate更新数据方法小结
- 教你轻松学会SQL Server记录轮班的技巧
