【问题标题】:How can I avoid SQL injection attacks in my ASP.NET application?如何在我的 ASP.NET 应用程序中避免 SQL 注入攻击?
【发布时间】:2010-09-23 05:35:32
【问题描述】:

我需要避免在我的 ASP.NET 应用程序中受到 SQL 注入的攻击。我怎样才能做到这一点?

【问题讨论】:

    标签: .net asp.net sql security sql-injection


    【解决方案1】:

    即使您的问题非常笼统,但始终适用一些规则:

    • 使用参数化查询(SqlCommandSqlParameter)并将用户输入放入参数中。
    • 不要根据未经检查的用户输入构建 SQL 字符串。
    • 不要假设您可以构建一个清理例程来检查用户输入的各种格式错误。边缘情况很容易被遗忘。检查数字输入可能很简单,可以保证您的安全,但对于字符串输入,只需使用参数。
    • 检查二级漏洞 - 如果 SQL 表值包含用户输入,则不要根据这些值构建 SQL 查询字符串。
    • 使用存储过程封装数据库操作。

    【讨论】:

    • 除了最后一个之外,所有这些都被第一个暗示(如果您的所有输入都被正确转义,总是通过使用准备好的语句(或参数化查询)),不是吗?或者你认为有细微的差别?
    • 没有。但是提出这类问题的人很可能对其中的含义没有明确的理解。使它们明确是支持理解。随着您的经验和抽象能力的提高,您将不再需要明确性,并且您不太可能再提出此类问题。
    • 这是一个很好的答案,但我觉得“使用存储过程封装数据库操作”具有误导性。参数化动态 SQL 与参数化存储过程一样安全。为了清楚起见,也许您应该在答案中更加隐含。
    • @Daniel:如果开发人员在数据库技术方面没有太多控制或专业知识,则可以使用与SqlCommand 一起使用的参数化查询。如果您是普通的 C# 开发人员而不是 DBA,那么在数据库中创建存储过程并不简单。如果 DBA 想要为 C# 开发人员封装复杂性,则使用存储过程是一种很好的方法。
    • @Vinko:我同意。将答案分成 2 个部分可以更好地回答:首先第 2-4 点作为您需要考虑的问题的答案,然后第 1 点和第 5 点作为解决所指出问题的可能解决方案。
    【解决方案2】:

    使用Prepared Statements(链接到使用“为产品添加节点”部分中的准备好的语句的 ASP.NET 教程)。这里的所有都是它的。

    好吧,或者使用 ORM,例如 Linq to SQLNHibernate,它们在内部使用预准备语句。

    【讨论】:

      【解决方案3】:

      使用参数!真的就是这么简单:-)

      像这样创建您的查询(对于使用 C# 的 MS Sql 服务器):

      SqlCommand getPersons = new SqlCommand("SELECT * FROM Table WHERE Name = @Name", conn); 
      

      这里@Name是你要避免sql注入的参数,conn是一个SqlConnection对象。 然后要添加参数值,请执行以下操作:

      getPersons.Parameters.AddWithValue("@Name", theName);
      

      这里 theName 是一个变量,其中包含您要搜索的名称。

      现在应该不可能对该查询进行任何 sql 注入。

      既然这么简单,就没有理由不使用参数。

      【讨论】:

        【解决方案4】:

        从不信任用户输入 - 使用验证控件、正则表达式、代码等验证所有文本框条目

        永远不要使用动态 SQL - 使用参数化 SQL 或存储过程

        永远不要使用管理员级别的帐户连接到数据库 - 使用受限访问帐户连接到数据库

        不要以纯文本形式存储机密 - 加密或散列密码和其他敏感数据;您还应该加密连接字符串

        异常应该泄露最少的信息 - 不要在错误消息中透露太多信息;在发生未处理的错误时使用 customErrors 显示最少的信息;将调试设置为 false

        MSDN 上的有用链接Stop SQL Injection

        【讨论】:

        • 很好的答案,但是,我不同意“从不使用动态 SQL”。动态 SQL 是一个非常通用的术语,可以非常强大,在很多情况下都应该使用它。您的观点应该只是将可变数据作为参数传递。
        • Aye Robin,我同意动态 SQL 可能非常有用,并且在一些很好的情况下应该使用它,根据我的观点,仅基于与外界用户的交互,停止他们注入SQL。例如,由 SQL 与用户输入的值连接构成的 SQL 语句。
        • 嗯,我刚刚获得了 -1 票,而且我下面的一些帖子让我们都失望了? (可能都是同一个用户??)
        【解决方案5】:

        SQL注入是因为对数据库的查询是实时构建的,例如:

        SELECT * From Table1 WHERE " + UserInput
        

        UserInput 可能是恶意的,并且包含您不希望的其他陈述。

        为避免这种情况,您需要避免将查询连接在一起。

        您可以通过使用参数化查询来完成此操作 - 查看 DBCommand 对象以了解您的特定数据库风格。

        【讨论】:

          【解决方案6】:

          使用参数化查询和/或存储过程并通过 SQL 参数解析您的参数。 从不通过连接字符串生成 SQL 代码。还要阅读有关 SQL 注入和编写安全代码的知识,因为防止 SQL 注入只是安全性的一小部分。还有更多(例如 XSS - 跨站点脚本)。如果黑客想要破坏您的站点/应用程序,他会寻找更多的东西,而不仅仅是 SQL 注入。

          【讨论】:

            【解决方案7】:

            Scott Guthrie posted a decent little article 不久前谈及此事。在其中,他提出了 5 条保护自己的建议:

            1. 不要在不使用类型安全参数编码机制的情况下构造动态 SQL 语句。 [...]

            2. 始终在将您的应用程序投入生产之前对其进行安全审查,并建立正式的安全流程以在您进行更新时审查所有代码。 [... ]

            3. 切勿在数据库中以明文形式存储敏感数据。 [...]

            4. 确保编写自动化单元测试,专门验证您的数据访问层和应用程序免受 SQL 注入攻击。 [...]

            5. 锁定您的数据库,只授予访问它的 Web 应用程序运行所需的最小权限集。 [...]

            他很好地解释了为什么这些很重要,并链接到其他几个资源......

            【讨论】:

            • 很重要,但只有第一个项目符号解决了 OP 的问题。
            【解决方案8】:

            从不信任用户输入,始终对其进行验证,并使用 sql 参数。应该有足够的基础来防止 SQL 注入。

            【讨论】:

              【解决方案9】:

              希望这会有所帮助:

              http://www.codersbarn.com/post/2008/11/01/ASPNET-Data-Input-Validation.aspx

              简短的回答是使用参数化查询。

              安东尼 :-) www.codersbarn.com

              【讨论】:

                【解决方案10】:

                始终只使用参数化查询。

                【讨论】:

                  【解决方案11】:

                  正如其他人所说,不要连接用户输入来创建动态 sql 语句;使用动态 SQL 时始终使用参数化 SQL。但是我要指出,在存储过程中创建动态 sql 时,该规则也适用。这个事实是人们经常忽略的。他们认为他们是安全的,因为他们“使用存储过程”。

                  【讨论】:

                    【解决方案12】:

                    “构建安全的 ASP.NET 应用程序”指南这本书有一个关于这个主题的section

                    【讨论】:

                      【解决方案13】:

                      使用 Microsoft.Security.Application.AntiXss.UrlEncode 使用 XSS 安全 UrlEncode 和 SQL 注入将不起作用。或者你可以使用 ASP.NET – JSON – 序列化和反序列化

                      还可以使用 Macfee Fre Tool 中的 SiteDigger 测试您的应用程序。

                      更多来自here

                      .NET 安全工具包 v1.0 .NETMon v1.0 Validator.NET v1.0

                      【讨论】:

                        【解决方案14】:

                        每个人都说“使用参数”。如果不是那么困难,我们就不得不少说。

                        使用QueryFirst。连接的诱惑被消除,正确的方法成为最简单的方法。您只需在 SQL 中键入 @myParam 即可创建参数,其余的由工具完成。

                        免责声明:我写的是 QueryFirst

                        【讨论】:

                          【解决方案15】:

                          了解究竟什么是 SQL 注入,然后永远不要编写任何易受其攻击的东西。

                          【讨论】:

                            【解决方案16】:

                            尝试使用存储过程,并验证数据的输入。不要使用任何直接的 SQL,例如 INSERT INTO ...

                            【讨论】:

                            • 存储过程与它无关,您可以通过不参数化调用以不安全的方式执行SP。
                            猜你喜欢
                            • 2011-01-13
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 2011-09-15
                            • 1970-01-01
                            • 1970-01-01
                            • 2015-11-30
                            相关资源
                            最近更新 更多