SqlParameter对象C# [重复]

Posted

技术标签:

【中文标题】SqlParameter对象C# [重复]【英文标题】:SqlParameter Object C# [duplicate] 【发布时间】:2012-10-04 11:52:46 【问题描述】:

可能重复:XKCD SQL injection — please explain

我是 C# 的新手,我想知道。

在C#中构建SQL字符串时,为什么我们需要使用SqlParameter对象来表示用户的输入,而不是直接传入字符串?

【问题讨论】:

请看一下那个问题。它解释了这一切,用比 C# SqlPatameter 更通用的术语,但仍然很好。 首先,C# 是一门语言,与数据库无关。实际的技术称为 ado.net,您要问的是参数化查询。 【参考方案1】:

我假设你的意思是为什么最好写:

command.Text = "SELECT LastName FROM MyUsers WHERE FirstName = @FirstName";
// Or whichever form...
command.Parameters.AddParameter("@FirstName").Value = input;

而不是

command.Text = "SELECT LastName FROM MyUsers WHERE FirstName = '" + input + "'";

后一种形式存在三个问题:

它允许SQL Injection Attacks 除非您非常小心地转义 - 上面的代码不是。想象一下,如果用户输入以下内容,SQL 会是什么样子:

' OR 'x' = 'x

它混合了代码和数据。你看不到你想要做什么的清晰表示,而第一种形式显示哪些位是固定的,哪些是可变输入

虽然对于 字符串 来说不是问题,但参数避免了不必要的数据转换。例如,当使用日期或日期/时间值时,使用第二种方法时,您最终需要担心数据库将接受哪些文本格式,即使您已经开始使用DateTime值(比方说),数据库将以某种适当的日期/时间类型的值结束。通过字符串表示只会带来麻烦。

此外,在某些情况下,第一种方法可能会提高性能,允许数据库缓存查询执行计划。不过,这方面有很多细微差别,而且是特定于数据库的。

【讨论】:

我发现很多人认为“哦,我的小网站不会成为 SQL 注入的目标,所以何必呢?”。这种思路的问题在于互联网是一个非常不安全的地方,并且有漫游机器人会尝试所有可能的 IP 地址,并尝试各种 SQL 注入攻击。您的网站可能被机器人入侵,然后被用来入侵其他网站或访问您网站的用户。更糟糕的是,它可能会变成垃圾邮件僵尸,并用于向他人发送垃圾邮件。不要错误地认为自己太小而不会受到攻击,因为这不是真的。 如果您的网站托管在商业托管系统上,您需要为带宽付费,那么您也可以学到一个非常昂贵的课程。你会发现自己突然欠了很多钱,因为你认为自己不够重要,可以攻击。需要记住的重要一点:在处理互联网时,请始终假设最坏的情况。【参考方案2】:

简单来说,为了避免 SQL 注入攻击,并且在某种程度上它还可以提高性能,因为我们为该参数指定了数据类型、大小等。

如果你只是想避免SQL注入,我想你可以使用

command.Text = "SELECT LastName FROM MyUsers WHERE FirstName = '" + input.Replace("'","''") + "'";

【讨论】:

以上是关于SqlParameter对象C# [重复]的主要内容,如果未能解决你的问题,请参考以下文章

数据库表增删查改帮助类

c#中SqlParameter用法

C#中,求一个返回类型为DataTable,并用SqlParameter传参的SqlHelper

System.Data.SqlClient.SqlParameter.IsNullable 的目的是啥?

“SqlParameterCollection 只接受非空的 SqlParameter 类型对象,不接受 String 对象”

将实体类/匿名对象转换为SqlParameter列表