如何在C#中为SqlServer转义简单的SQL查询

我使用一个需要SQLstring的API。 我接受用户input,将其转义并传递给API。 用户input非常简单。 它要求列值。 像这样:

string name = userInput.Value; 

然后我构造一个SQL查询:

 string sql = string.Format("SELECT * FROM SOME_TABLE WHERE Name = '{0}'", name.replace("'", "''")); 

这安全吗? 如果不是,是否有一个简单的库函数使列值安全:

 string sql = string.Format("SELECT * FROM SOME_TABLE WHERE Name = '{0}'", SqlSafeColumnValue(name)); 

该API使用SQLServer作为数据库。

由于使用SqlParameter不是一个选项,只需在string中replace'with'(这是两个单引号,而不是一个双引号)。 而已。

要成为下stream者:重新阅读问题的第一行。 “使用参数”也是我的直觉反应。

编辑:是的,我知道SQL注入攻击。 如果您认为这个引用容易受到这些影响,请提供一个有效的反例。 我觉得不是。

简单:

 const string sql = "SELECT * FROM SOME_TABLE WHERE Name = @name"; 

并添加值为@name参数:

 cmd.CommandText = sql; cmd.Parameters.AddWithValue("@name", name); 

我正在使用dynamicsql(我可以听到加载他们的步枪射击队)的searchfunction,但它会打破每当用户search像“O'Reilly”姓氏的人。

我设法找出一个解决办法(读“黑客”):

在sql中创build了一个标量值函数,用两个单引号replace单引号,从而有效地转义了违规单引号
“…姓氏LIKE'%O'Reilly%'和…'变成”…姓氏LIKE'%O''Reilly%'…“

当我怀疑字段可能包含单引号字符,即:firstname,lastname时,该函数从sql中调用。

 CREATE FUNCTION [dbo].[fnEscapeSingleQuote] (@StringToCheck NVARCHAR(MAX)) RETURNS NVARCHAR(MAX) AS BEGIN DECLARE @Result NVARCHAR(MAX) SELECT @Result = REPLACE(@StringToCheck, CHAR(39), CHAR(39) + CHAR(39)) RETURN @Result END 

不是非常优雅或高效,但它在你处于困境时起作用。

当需要在短时间内解决大量ad hoc sql中的问题时,可能希望用“replace”而不是参数化,同时破坏风险最小,testing最less。

最好使用sql参数,但是对查询有2300个参数的限制。 在大多数情况下,这将是绰绰有余。 但在极less数情况下,当你超过这个限制时,我认为这是一个select。

SqlCommand和Entity Framework使用exec sp_executesql...

所以真的有一个替代原始string与你自己的逃避模式大概。 使用SqlCommand,您在技术上使用参数化查询,但是绕过了底层SQL代码的ADO.Net抽象。

所以虽然你的代码不能阻止SQL注入,但最终的答案是sp_executesql而不是SqlCommand。

话虽如此,我相信有一些特殊的处理要求,用于生成一个使用sp_executesql的SQL注入certificatestring。

请参阅: 如何将dynamicSQL存储过程的值返回给entity framework?

如果您需要为MSSQL查询转义string,请尝试以下操作:

 System.Security.SecurityElement.Escape(Value)