AddWithValue sql注入安全吗?为什么?

时间:2014-01-21 16:18:56

标签: c# sql

我希望这是一个正确的地方,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();
}

3 个答案:

答案 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参数允许对数据进行类型安全和长度检查。启用S​​QL注入防御,它们不会完全禁止SQL注入,您仍然需要检查输入。

关于类似主题的

SO Answer

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表中的所有记录。