您的位置:首页 > 职场人生

【黑马程序员】连接数据库时的注入漏洞攻击

2013-08-22 20:45 260 查看
----------------------
ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------

在使用ADO.Net连接数据库时,我们有时会要求从界面输入登录名和密码,然后把登录名和密码传入数据库进行验证,以确定用户是否可以登录。如下面就是一个简单的登录程序。

static void Main(string[] args)
{
string connStr = "Data Source = .;Initial Catalog = MySchoolBase;User Id = sa;Pwd = 1234;";

Console.WriteLine("请输入用户名:");
string username = Console.ReadLine();
Console.WriteLine("请输入密码:");
string password = Console.ReadLine();
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "select count(*) from Admin where LoginName = '" + username +
"' and LoginPwd = '" + password + "'";
int result = (int)cmd.ExecuteScalar();
if (result == 1)
{
Console.WriteLine("登陆成功!");
}
else
{
Console.WriteLine("登陆失败!");
}
}
}

Console.ReadKey();
}

运行这个程序,结果如下:





乍一看上去,密码输入正确,登录成功,密码输入错误,登录失败!这个登录程序已经很完美了。其实不然,看下面的两图:



当我们再输入一串怪异的字符串时,我们仍然会登录成功。这是怎么回事呢?我们先检查一下数据库MySchoolBase里面的Admin表,看看是否有这样的用户名和密码:


我们可以看到,数据库里面并没有这样的登录名和密码,这种现象就是注入漏洞攻击。当我们输入1' or '1' = '1 这样怪异字符串之后,经过调试,可以看到命令语句变成了select count(*) from Admin where LoginName = '1' or '1' = '1' and LoginPwd = '1' or '1' = '1' ,这就造成了where语句永远成立,然后就可以登录成功了。

那该怎么办呢?可以防止这样的漏洞吗?当然可以,因为那样进行拼接的字符串在执行的时候,程序会把它当作一条语句来执行,这条语句里的字符串就是那几个1。我们只要把用户输入的怪异字符串整体当成一个真正的字符串赋值给LoginName和LoginPwd进行处理,就可以避免这种漏洞。VS给我们提供了一个参数化查询:SqlParameter,通过它,我们可以把用户输入的字符串参数化,把它整体当作一个参数传递给命令语句。具体用法见代码:

static void Main(string[] args)
{
string connStr = "Data Source = .;Initial Catalog = MySchoolBase;User Id = sa;Pwd = 1234;";

Console.WriteLine("请输入用户名:");
string username = Console.ReadLine();
Console.WriteLine("请输入密码:");
string password = Console.ReadLine();
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
//使用@占位符形式写sql语句
cmd.CommandText = "select count(*) from Admin where LoginName = @LN and LoginPwd = @LP";
//以用户输入的字符串建立参数对象后添加到命令语句的参数集合
cmd.Parameters.Add(new SqlParameter("LN", username));
cmd.Parameters.Add(new SqlParameter("LP", password));
int result = (int)cmd.ExecuteScalar();
if (result == 1)
{
Console.WriteLine("登陆成功!");
}
else
{
Console.WriteLine("登陆失败!");
}
}
}

Console.ReadKey();
}

运行后,我们继续输入那个怪异字符串,结果如图所示:



这样就可以有效的防止这种注入漏洞攻击!

----------------------
ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: