使用参数化的 SqlCommand 是不是使我的程序免受 SQL 注入的影响?

Posted

技术标签:

【中文标题】使用参数化的 SqlCommand 是不是使我的程序免受 SQL 注入的影响?【英文标题】:Does using parameterized SqlCommand make my program immune to SQL injection?使用参数化的 SqlCommand 是否使我的程序免受 SQL 注入的影响? 【发布时间】:2011-11-02 17:44:07 【问题描述】:

我知道SQL injection is rather dangerous。现在在我的 C# 代码中,我使用 SqlCommand class 编写参数化查询:

SqlCommand command = ...;
command.CommandText = "SELECT * FROM Jobs WHERE JobId = @JobId;";
command.Parameters.Add("@JobId", SqlDbType.UniqueIdentifier ).Value = actualGuid;
command.ExecuteNonQuery();

这会自动使我的代码免受 SQL 注入的影响吗?我需要做一些额外的事情吗?

【问题讨论】:

【参考方案1】:

我会说对于参数化查询的特定且可能是规范的示例,是的,这就足够了。

但是,人们有时会编写这样的代码

cmd.CommandText = string.Format("SELECT * FROM 0 WHERE col = @col;", tableName);
cmd.Parameters.Add("@col", ...);

因为根本无法将表名本身作为参数传递,并且有时存在这样做的愿望 - 是否被误导。似乎它经常被忽视,tableName(除非可能只从一组不从任何输入派生的静态/常量值读取)确实允许 SQL 注入。

【讨论】:

【参考方案2】:

根据this MSDN Article 上的注释,“特殊输入字符仅对动态 SQL 构成威胁,而在使用参数化 SQL 时不构成威胁。”

所以我相信你可以安全地抵御 SQL 注入。在 URL 中使用标识符(如身份值)可能存在一些逻辑风险,但这是另一回事。

【讨论】:

【参考方案3】:

SQL 注入主要依赖于动态 SQL 的执行。换言之,SQL 语句由 SQL 与用户输入的值连接而成。

为了完全避免 SQL 注入,

保护自己免受 SQL 注入攻击并不是很困难。不受 SQL 注入攻击影响的应用程序会验证和清理所有用户输入,从不使用动态 SQL,使用很少特权的帐户执行,散列或加密其秘密,并显示错误消息,即使没有有用的信息也很少向黑客透露。通过采用多层次的预防方法,您可以放心,如果一种防御措施被规避,您仍然会受到保护。

来自MSDN

【讨论】:

【参考方案4】:

使用 SqlCommand 是一种非常好的做法,只要您不在任何地方(包括在您调用的任何存储过程中——即避免动态 SQL)连接 SQL 字符串,您就不会受到 SQL 注入攻击。

【讨论】:

【参考方案5】:

如果您使用动态 sql,即使您通过参数传递它,您也无法免疫 SQL 注入。太糟糕了,SQL Server 没有内置函数来清理参数

【讨论】:

引文?上面引用的 MSDN 文章似乎与您的回答相矛盾。 对于动态查询,如果您在将参数发送到查询之前没有对参数进行清理,您可以轻松地通过参数插入 sql 注入。自己试试吧。

以上是关于使用参数化的 SqlCommand 是不是使我的程序免受 SQL 注入的影响?的主要内容,如果未能解决你的问题,请参考以下文章

更改表 SqlCommand

更改表 SqlCommand

如何使用替换的参数捕获 SQL? (.NET,SqlCommand)

带参数的 SqlCommand

SqlCommand 和 SqlDataAapter 的参数

SqlCommand 参数 Add 与 AddWithValue [重复]