使用参数化的 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 注入的影响?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用替换的参数捕获 SQL? (.NET,SqlCommand)