【问题标题】:How to prevent a SQL Injection escaping strings如何防止 SQL 注入转义字符串
【发布时间】:2011-09-26 17:45:36
【问题描述】:

我有一些查询(访问数据库)是这样的:

string comando = "SELECT * FROM ANAGRAFICA WHERE E_MAIL='" + user + "' AND PASSWORD_AZIENDA='" + password + "'";

我想“转义”用户和密码,防止注入。

如何使用 C# 和 .NET 3.5 来做到这一点?我在 PHP 上搜索类似 mysql_escape_string 的东西...

【问题讨论】:

    标签: c# .net sql-injection


    【解决方案1】:

    您需要使用参数。好吧,不必这样做,但会更好。

    SqlParameter[] myparm = new SqlParameter[2];
    myparm[0] = new SqlParameter("@User",user);
    myparm[1] = new SqlParameter("@Pass",password);
    
    string comando = "SELECT * FROM ANAGRAFICA WHERE E_MAIL=@User AND PASSWORD_AZIENDA=@Pass";
    

    【讨论】:

    • 不一定需要使用,但它们是最好的选择并且可靠地工作;-)。可能每一个本土变种都会有一些问题。
    • @Jethro :但是之后,我可以将实际值传递给查询吗?我需要将 myparam 数组传递给 SqlExecute 查询,不是吗?
    • @Markzzz,是的,您需要将 sql 参数与查询一起传递,以便执行。将实际值传递给查询是什么意思?您会将实际值传递给构建查询的参数。
    • 所以上面的代码(没有任何代码)应该可以工作吗?事实上它没有。现场用户转义到 myparm[0] 对吗?查询不知道该参数...
    • 我的意思是:我不需要将这些参数添加到 SQL 连接?
    【解决方案2】:

    不要转义开头的字符串 - 使用参数化查询。转义的好处:

    • 代码更容易阅读
    • 您不必依赖转义正确
    • 可能会有性能改进(特定于 DB 等)
    • 它将“代码”(SQL)与数据分开,这在逻辑上很合理
    • 这意味着您无需担心数字和日期/时间等数据格式。

    SqlCommand.Parameters 的文档提供了一个很好的完整示例。

    【讨论】:

      【解决方案3】:

      您应该使用 SQL 参数来防止 SQL 注入 看代码

      //
      // The name we are trying to match.
      //
      string dogName = "Fido";
      //
      // Use preset string for connection and open it.
      //
      string connectionString = ConsoleApplication716.Properties.Settings.Default.ConnectionString;
      using (SqlConnection connection = new SqlConnection(connectionString))
      {
          connection.Open();
          //
          // Description of SQL command:
          // 1. It selects all cells from rows matching the name.
          // 2. It uses LIKE operator because Name is a Text field.
          // 3. @Name must be added as a new SqlParameter.
          //
          using (SqlCommand command = new SqlCommand("SELECT * FROM Dogs1 WHERE Name LIKE @Name", connection))
          {
          //
          // Add new SqlParameter to the command.
          //
          command.Parameters.Add(new SqlParameter("Name", dogName));
          //
          // Read in the SELECT results.
          //
          SqlDataReader reader = command.ExecuteReader();
          while (reader.Read())
          {
              int weight = reader.GetInt32(0);
              string name = reader.GetString(1);
              string breed = reader.GetString(2);
              Console.WriteLine("Weight = {0}, Name = {1}, Breed = {2}", weight,    name, breed);
          }
          }
      }
      

      【讨论】:

        【解决方案4】:

        是的,您可以使用Named Parameters避免注入

        【讨论】:

          【解决方案5】:

          使用参数而不是转义字符串:

          var comando = "SELECT * FROM ANAGRAFICA WHERE E_MAIL=@user AND PASSWORD_AZIENDA=@password";
          

          然后在执行SqlCommand之前为这些参数赋值。

          【讨论】:

            【解决方案6】:

            您可以查看以下链接以了解如何防止 ASP.Net 中的 SQL 注入。我更喜欢使用

            1. 使用参数化查询或存储过程。
            2. 验证特殊字符,如 '(非常危险)

            http://dotnet.dzone.com/news/aspnet-preventing-sql-injectio

            【讨论】:

              【解决方案7】:

              如果您可以将这些转换为命名参数,我认为您会得到更好的服务。

              【讨论】:

              • 好点,命名参数将是 C#/.NET 中的必然结果。
              【解决方案8】:

              @Jethro

              你也可以这样写:

              SqlParameter[] sqlParams = new SqlParameter[] {
                  new SqlParameter("@Name", contact.name),
                  new SqlParameter("@Number", contact.number),
                  new SqlParameter("@PhotoPath", contact.photoPath),
                  new SqlParameter("@ID", contact.id)
              };
              

              【讨论】:

                【解决方案9】:

                PT: Siga os passos a seguir e resolva o problema de SQL INJECTION

                EN:按照以下步骤解决 SQL INJECTION 问题:

                ES:Siga los siguientes pasos y resolver el problema de la inyección de SQL:

                OracleParameter[] tmpParans = new OracleParameter[1];
                
                tmpParans[0] = new Oracle.DataAccess.Client.OracleParameter("@User", txtUser.Text);
                
                string tmpQuery = "SELECT COD_USER, PASS FROM TB_USERS WHERE COD_USER = @User";
                
                OracleCommand tmpComand = new OracleCommand(tmpQuery, yourConnection);
                
                tmpComand.Parameters.AddRange(tmpParans);
                
                
                OracleDataReader tmpResult = tmpComand.ExecuteReader(CommandBehavior.SingleRow);
                

                【讨论】:

                  猜你喜欢
                  • 2010-12-21
                  • 2010-10-06
                  • 2020-09-28
                  • 1970-01-01
                  • 2010-11-08
                  • 2011-03-18
                  • 1970-01-01
                  • 2015-09-14
                  • 1970-01-01
                  相关资源
                  最近更新 更多