我有一个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 { }
}
当我使用此登录'' or 1=1 --
尝试Sql注入攻击时,攻击失败。但是,如果我改变这个片段:
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注入攻击的最佳方法是什么?
答案 0 :(得分: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.gethashcode.aspx
答案 1 :(得分:2)
始终使用命令参数来避免sql注入。 Sql注入由命令参数自动处理。如果使用命令参数,则无需担心sql注入。
当您不使用命令参数时,参数的值只是插入sql查询而不处理sql注入。但是当你使用命令参数时,ADO.Net会为你处理sql注入。