谷歌变成了各种各样的消毒Web访问查询的讨论,但我没有找到任何解决什么,我关心的是:在C#程序消毒SQL数据
消毒用户输入数据。这必须通过可逆转化来完成,而不是通过去除。作为问题的一个简单例子,我不想破坏爱尔兰人的名字。
什么是最好的方法,是否有任何库函数呢?
谷歌变成了各种各样的消毒Web访问查询的讨论,但我没有找到任何解决什么,我关心的是:在C#程序消毒SQL数据
消毒用户输入数据。这必须通过可逆转化来完成,而不是通过去除。作为问题的一个简单例子,我不想破坏爱尔兰人的名字。
什么是最好的方法,是否有任何库函数呢?
这取决于您使用的SQL数据库。例如,如果你想在MySQL中使用单引号,你需要使用一个反斜杠Dangerous:'
和一个逃脱的转义字符:\'
。对于MS-SQL,情况完全不同,危险:'
转义:''
。当您以这种方式转义数据时,不会删除任何内容,它是一种表示控制字符的方式,如字面形式的引号。
下面是使用MS-SQL和C#参数化查询,从Docs采取的一个例子:
private static void UpdateDemographics(Int32 customerID,
string demoXml, string connectionString)
{
// Update the demographics for a store, which is stored
// in an xml column.
string commandText = "UPDATE Sales.Store SET Demographics = @demographics "
+ "WHERE CustomerID = @ID;";
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand(commandText, connection);
command.Parameters.Add("@ID", SqlDbType.Int);
command.Parameters["@ID"].Value = customerID;
// Use AddWithValue to assign Demographics.
// SQL Server will implicitly convert strings into XML.
command.Parameters.AddWithValue("@demographics", demoXml);
try
{
connection.Open();
Int32 rowsAffected = command.ExecuteNonQuery();
Console.WriteLine("RowsAffected: {0}", rowsAffected);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
对于MySQL我不知道,你可以使用参数化查询库。您应该使用mysql_real_escape_string()或者任意使用此功能。:
public static string MySqlEscape(this string usString)
{
if (usString == null)
{
return null;
}
// SQL Encoding for MySQL Recommended here:
// http://au.php.net/manual/en/function.mysql-real-escape-string.php
// it escapes \r, \n, \x00, \x1a, baskslash, single quotes, and double quotes
return Regex.Replace(usString, @"[\r\n\x00\x1a\\'""]", @"\$0");
}
我意识到这是一个较旧的帖子,但PHP [5.0 +]确实通过MySQLi(http://php.net/manual/en/book.mysqli.php)和PDO库(http:///php.net/manual/en/book.pdo.php)。 – 2012-06-19 09:52:06
@Tieson T.和adodb,以及参数化查询是最好的选择。 – rook 2012-06-19 17:42:13
fyi,mysql_real_escape_string已被弃用 – 2013-04-22 18:29:36
使用适当构造的DAL与SQL参数对象交给存储过程,您不必担心这一点。实现业务对象和dal以足够抽象用户输入,以使其不作为SQL执行,而是作为值进行识别。示例很有趣:
public class SomeDal
{
public void CreateUser(User userToBeCreated)
{
using(connection bla bla)
{
// create and execute a command object filling its parameters with data from the User object
}
}
}
public class User
{
public string Name { get; set; }
...
}
public class UserBL
{
public CreateUser(User userToBeCreated)
{
SomeDal myDal = new SomeDal();
myDal.CreateUser(userToBeCreated);
}
}
public class SomeUI
{
public void HandleCreateClick(object sender, e ButtonClickEventArgs)
{
User userToBeCreated = new User() { Name = txtName.Text };
UserBL userBl = new UserBL();
userBl.CreateUser(userToBeCreated);
}
}
我看到parematerized命令是要走的路,但您的示例代码与它们无关! – 2010-08-13 20:26:33
@Loren Pechtel:评论说要使用它们,而且你希望你的用户输入填充一个像User的业务对象,它充当传输到dal的业务对象,它创建命令和参数。这种抽象将数据库中的用户与安全性分离,因为你可以创建一个UserValidator和其他类似的东西,使得他们的输入不仅可以从SQL注入中安全使用,而且可以避免无效值。 – 2010-08-13 20:31:34
我同意你需要一个检查有效性的层次,但这与保持系统免于奥尼尔先生的窒息是分开的。 – 2010-08-14 04:51:36
是否将可能包含撇号的数据传递给SQL查询?如果您使用SQL Parameter对象,那应该不成问题。你会得到你的消毒,并且你的数据中的任何重要字符都应该被正确地转义。 – 2010-08-13 17:53:02
同意的参数化查询是可行的方法。 – driis 2010-08-13 17:57:53
我只通过业务逻辑生成SQL查询。 – Jeroen 2010-08-13 18:11:45