1

我有一个 asp.net 应用程序。我在其中有这段代码:

 using (Data.connexion)
    {
        string queryString = @"select id_user , nom, prenom, mail, login, mdp, last_visite, id_group, id_user_status from USERS where login =@login and mdp=@mdp";
        SqlCommand command = new SqlCommand(queryString, Data.connexion);
        command.Parameters.AddWithValue("@login", _login);
        command.Parameters.AddWithValue("@mdp", _password.GetHashCode().ToString());
        try
        {
            SqlDataReader reader = command.ExecuteReader();
            do
            {
                while (reader.Read())
                {
                    return View("Success");
                }
            } while (reader.NextResult());

        }
        catch {  }
    }

当我尝试使用此登录名进行 Sql 注入攻击'' or 1=1 --时,攻击失败。但是如果我用这个更改片段:

 using (Data.connexion)
            {
                string queryString = @"select id_user , nom, prenom, mail, login, mdp, last_visite, id_group, id_user_status from USERS where login =" + _login + " and mdp=" + _password.GetHashCode().ToString();
                SqlCommand command = new SqlCommand(queryString, Data.connexion);
              //  command.Parameters.AddWithValue("@login", _login);
               // command.Parameters.AddWithValue("@mdp", _password.GetHashCode().ToString());
                try
                {
                    SqlDataReader reader = command.ExecuteReader();
                    do
                    {
                        while (reader.Read())
                        {
                            return View("Success");
                        }
                    } while (reader.NextResult());

                }
                catch {  }
            }

我被重定向到视图success,因此攻击成功。

两种编码方式有什么区别?预防和避免 Sql 注入攻击的最佳方法是什么?

4

2 回答 2

3

防止 SQL 注入的最佳方法是使用参数化查询。

将值连接成字符串时可以使其安全,但必须完全正确,并且数据库品牌之间的确切方法不同。

对于 SQL Server,您可以通过将字符串中的任何撇号加倍来对字符串值进行编码。这样,数据库将正确解释任何撇号,并且不可能使用撇号从字符串中分离出来:

string queryString = "select id_user, nom, prenom, mail, login, mdp, last_visite, id_group, id_user_status from USERS where login = '" + _login.Replace("'","''") + "' and mdp = '" + _password.GetHashCode().ToString().Replace("'","''") + "'";

但是,使用参数化查询仍然更容易,然后数据库驱动程序会为您执行此操作。如果您尝试自己处理编码,但没有正确处理,那么您将处于更糟糕的位置,因为您认为问题已得到处理,但它很容易受到 SQL 注入攻击。


旁注:该String.GetHashCode方法不适用于散列密码之类的事情。该方法的实现将来可能会发生变化(就像过去一样),这将使数据库中的所有散列密码都变得无用。

“不要序列化哈希码值或将它们存储在数据库中。” -- http://msdn.microsoft.com/en-us/library/system.string.getashcode.aspx

于 2013-09-03T16:14:23.480 回答
2

始终使用命令参数来避免 sql 注入。Sql 注入由命令参数自动处理。如果使用命令参数,则无需担心 sql 注入。

当您不使用命令参数时,参数的值只是简单地插入到 sql 查询中,而不处理 sql 注入。但是当您使用命令参数时,ADO.Net 会为您处理 sql 注入。

于 2013-09-03T16:11:26.903 回答