【问题标题】: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 注入的影响吗?我需要做一些额外的事情吗?

【问题讨论】:

    标签: c# .net sql security sql-injection


    【解决方案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 注入。自己试试吧。
            猜你喜欢
            • 2011-07-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-12-28
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多