我希望这是一个正确的地方,parameters.addwithvalue
如何运作?我正在考虑防止SQL注入?我一直在Stackoverflow上看很多,很多人说“//反对sql注入”。我一直在盲目地使用它,但现在我必须提交一份关于我的任务的文章,我需要解释为什么它是保护。我一直试图在MSDN上找到一些东西,找到了这个:
SQL injection但它使用parameters.add
。然后我读到他们用.Add
替换.AddWithValue
,这是真的吗?关于此的任何官员呢?
所以基本上,任何人都可以更好地搜索一些防止SQL注入的官方文书工作?或者可以告诉我它是如何工作的?
我不是想让你做我的工作,我只是找不到自己。
我正在使用它:
using (SqlConnection conn = new SqlConnection(connectionString))
using (var cmd = conn.CreateCommand())
{
conn.Open();
String queryString = "DELETE FROM dbo.SecurityAccess WHERE Username = ' @Username ";
cmd.CommandText = queryString;
cmd.Parameters.AddWithValue("@Username", Username);
cmd.ExecuteNonQuery();
}
答案 0 :(得分:5)
从SQL注入的角度来看,使用参数通常是安全的(取决于您在SQL中使用这些参数做什么...)。你的例子是安全的。如何添加参数与SQL Ibjection的观点没有区别,但与ADO.Net和SQL性能的观点有很大不同。由于与参数类型和大小相关的性能问题,AddWithValue
是反模式。在您的示例中,@UserName
将是NVARCHAR
类型的参数,这可能会使WHERE Username=@UserName
谓词不可用(不会使用用户名上的索引)。执行结果会很糟糕。
数据类型转换的潜在解决方案是使用显式Add
方法而不是AddWithValue
,它将数据类型作为第二个参数。有关此here的详细信息。
有关详细信息,我建议您阅读How Data Access Code Affects Database Performance。
答案 1 :(得分:3)
In Short参数允许对数据进行类型安全和长度检查。启用SQL注入防御,它们不会完全禁止SQL注入,您仍然需要检查输入。
关于类似主题的Good article解释参数如何不阻止SQL注入100%
SQL注入示例(取自MSDN :)
考虑当用户在SSN文本框中键入以下字符串时会发生什么,该文本框期望社会安全号码为nnn-nn-nnnn。 '; DROP DATABASE pubs -
使用输入,应用程序执行以下动态SQL语句或存储过程,该语句在内部执行类似的SQL语句。
// Use dynamic SQL
SqlDataAdapter myCommand = new SqlDataAdapter(
"SELECT au_lname, au_fname FROM authors WHERE au_id = '" +
SSN.Text + "'", myConnection);
// Use stored procedures
SqlDataAdapter myCommand = new SqlDataAdapter(
"LoginStoredProcedure '" +
SSN.Text + "'", myConnection);
开发人员的意图是,当代码运行时,它会插入用户的输入并生成以下语句的SQL。
SELECT au_lname, au_fname FROM authors WHERE au_id = '172-32-9999'
但是,代码会插入用户的恶意输入并生成以下查询。
SELECT au_lname, au_fname FROM authors WHERE au_id = ''; DROP DATABASE pubs --
“
避免注入攻击的常用方法。
•限制和消毒输入数据。通过验证类型,长度,格式和范围来检查已知的良好数据。
•使用类型安全的SQL参数进行数据访问。您可以将这些参数与存储过程或动态构造的SQL命令字符串一起使用。参数集合(如SqlParameterCollection)提供类型检查和长度验证。如果使用参数集合,则将输入视为文字值,SQL Server不将其视为可执行代码。使用参数集合的另一个好处是可以强制执行类型和长度检查。超出范围的值会触发异常。这是深度防守的一个很好的例子。
•使用数据库中具有受限权限的帐户。理想情况下,您应该只向数据库中的选定存储过程授予执行权限,并且不提供直接表访问。
•避免披露数据库错误信息。如果出现数据库错误,请确保您没有向用户披露详细的错误消息。
答案 2 :(得分:1)
如果您不使用带有上述命令的参数化查询,则它看起来像:
string queryString="DELETE FROM dbo.SecurityAccess WHERE Username = '"+txtUserName.Text+"'";
在上面的命令用户名中将分配用户在TextBox中输入的内容(例如:txtUserName
)。
如果用户想要注入某些行为(添加删除/更新或他想做的任何事情),他可以在TextBox中输入以下内容(txtUserName
)
=> "'';delete * from users"
然后具有给定username
值的上述命令如下所示:
string queryString="DELETE FROM dbo.SecurityAccess WHERE Username = '';delete * from users";
最后,上述命令将删除users
表中的所有记录。