关于SQL漏洞注入(Ado.Net)

SQL漏洞注入是常见的一种攻击方式,我们可以通过一些简单的方式来预防。看一下我们经常写的代码:

   1: /// <summary>
   2: /// 不安全的登录代码
   3: /// </summary>
   4: /// <param name="sender"></param>
   5: /// <param name="e"></param>
   6: private void button2_Click(object sender, EventArgs e)
   7: {
   8:     string connString = "server=.;database=userinfo;uid=sa;pwd=123456";
   9:     using (SqlConnection conn = new SqlConnection(connString))
  10:     {
  11:         conn.Open();
  12:         string sql = string.Format("select * from userinfo where username = '{0}' and userpwd='{1}'", textBox1.Text, textBox2.Text);
  13:         using (SqlCommand cmd = new SqlCommand(sql, conn))
  14:         {
  15:             using (SqlDataReader reader = cmd.ExecuteReader())
  16:             {
  17:                 if (reader.Read())
  18:                 {
  19:                     MessageBox.Show("Success!");
  20:                 }
  21:                 else
  22:                 {
  23:                     MessageBox.Show("Error");
  24:                 }
  25:             }
  26:         }
  27:     }
  28: }

数据库的结构:

image

运行程序:

image

SQL漏洞注入:

方式一(知道用户名):

当在用户名文本框中输入 tom ’ -- 点击登录按钮:

image

原因是生成后的SQL成了如下形式:

   1: select * from userinfo where username = 'tom ' --' and userpwd=''

--是SQL中的注释

方式二(不知道用户名密码):

当在用户名文本框中输入 ' or 1=1 -- 点击登录按钮:

image

生成后的SQL:

   1: select * from userinfo where username = '' or 1=1 --' and userpwd=''

--依然是注释,但是or促成了1=1条件的永远成立。

 

预防方式一(使用带参数的SQl):

   1: /// <summary>
   2: /// 安全登录
   3: /// </summary>
   4: /// <param name="sender"></param>
   5: /// <param name="e"></param>
   6: private void button3_Click(object sender, EventArgs e)
   7: {
   8:     try
   9:     {
  10:         string connString = "server=.;database=userinfo;uid=sa;pwd=123456";
  11:         using (SqlConnection conn = new SqlConnection(connString))
  12:         {
  13:             conn.Open();
  14:             string sql = "select * from userinfo where username = @id and userpwd= @pwd";
  15:             using (SqlCommand cmd = new SqlCommand(sql, conn))
  16:             {
  17:                 cmd.Parameters.Add(new SqlParameter("@id", textBox1.Text));
  18:                 cmd.Parameters.Add(new SqlParameter("@pwd", textBox2.Text));
  19:                 using (SqlDataReader reader = cmd.ExecuteReader())
  20:                 {
  21:                     if (reader.Read())
  22:                     {
  23:                         MessageBox.Show("Success!");
  24:                     }
  25:                     else
  26:                     {
  27:                         MessageBox.Show("Error");
  28:                     }
  29:                 }
  30:             }
  31:         }
  32:     }
  33:     catch (Exception ex)
  34:     {
  35:         MessageBox.Show(ex.Message.ToString());
  36:        
  37:     }
  38: }

运行:

image image

方式二(使用存储过程):

存储过程:

   1: create proc findUser
   2: @name nvarchar(50),
   3: @pwd nvarchar(50)
   4: as 
   5: select * from userinfo where username = @name and userpwd = @pwd

代码:

   1: /// <summary>
   2: /// 安全登录
   3: /// </summary>
   4: /// <param name="sender"></param>
   5: /// <param name="e"></param>
   6: private void button3_Click(object sender, EventArgs e)
   7: {
   8:     try
   9:     {
  10:         string connString = "server=.;database=userinfo;uid=sa;pwd=123456";
  11:         using (SqlConnection conn = new SqlConnection(connString))
  12:         {
  13:             conn.Open();
  14:             using (SqlCommand cmd = new SqlCommand("finduser", conn))
  15:             {
  16:                 cmd.CommandType = CommandType.StoredProcedure;
  17:                 cmd.Parameters.Add(new SqlParameter("@name", textBox1.Text));
  18:                 cmd.Parameters.Add(new SqlParameter("@pwd", textBox2.Text));
  19:                 using (SqlDataReader reader = cmd.ExecuteReader())
  20:                 {
  21:                     if (reader.Read())
  22:                     {
  23:                         MessageBox.Show("Success!");
  24:                     }
  25:                     else
  26:                     {
  27:                         MessageBox.Show("Error");
  28:                     }
  29:                 }
  30:             }
  31:         }
  32:     }
  33:     catch (Exception ex)
  34:     {
  35:         MessageBox.Show(ex.Message.ToString());
  36:        
  37:     }
  38: }
运行结果同上。
posted @ 2009-01-07 23:37  樊凯  阅读(1261)  评论(2编辑  收藏  举报