可能重复:
XKCD SQL 注入——请解释
我是 C# 的新手,我想知道。
在 C# 中构建 SQL 字符串时,为什么我们需要使用 SqlParameter 对象来表示用户的输入,而不是直接传入字符串?
可能重复:
XKCD SQL 注入——请解释
我是 C# 的新手,我想知道。
在 C# 中构建 SQL 字符串时,为什么我们需要使用 SqlParameter 对象来表示用户的输入,而不是直接传入字符串?
我假设您的意思是为什么最好写:
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 注入攻击,除非您对转义非常小心 - 上面的代码不是。想象一下,如果用户输入以下内容,SQL 会是什么样子:
' OR 'x' = 'x
它混合了代码和数据。你看不到你想要做什么的清晰表示,而第一种形式显示哪些位是固定的,哪些是可变输入
虽然对于字符串来说不是问题,但参数避免了不必要的数据转换。例如,当使用日期或日期/时间值时,使用第二种方法时,您最终需要担心数据库将接受哪些文本格式,即使您从一个DateTime
值开始(比如说)并且数据库最终会具有某种适当的日期/时间类型的值。通过字符串表示只会带来麻烦。
此外,在某些情况下,第一种方法可能会提高性能,允许数据库缓存查询执行计划。不过,这方面有很多细微差别,而且它是特定于数据库的。
简单来说,为了避免 SQL 注入攻击,并且在某种程度上它还可以提高性能,因为我们为该参数指定了数据类型、大小等。
如果你只是想避免 SQL 注入,我想你可以使用
command.Text = "SELECT LastName FROM MyUsers WHERE FirstName = '" + input.Replace("'","''") + "'";