码迷,mamicode.com
首页 > 其他好文 > 详细

浅谈注入漏洞问题

时间:2016-07-13 13:46:50      阅读:144      评论:0      收藏:0      [点我收藏+]

标签:

1、分析

     在客户端进行身份认证登录的时候,有时候会面临字符串的脚本注入漏洞,可能会因为sql字符串的书写而添加了多个逻辑运算符进而出现账号密码的“强制匹配”。也比如说在网站中插入某个恶意的脚本窃取用户的Cookie,进而盗用客户的信息。这些问题都有可能会导致用户信息和安全的泄露。

       要防止SQL注入其实不难,你知道原理就可以了。所有的SQL注入都是从用户的输入开始的。如果你对所有用户输入进行了判定和过滤,就可以防止SQL注入了。用户输入有好几种,我就说说常见的吧。
        文本框、地址栏里***.asp?中?号后面的id=1之类的、单选框等等。一般SQL注入都用地址栏里的,或者在密码输入文本框中输入1’or‘1’=‘1’或者在用户名输入框中输入‘‘ or 1=1#.

 

2、场景模拟

      我们在登录界面中的按钮中点击事件中输入:

 1  private void btnLogin_Click(object sender, EventArgs e)
 2         {
 3             // 如何表示登陆成功了?
 4             // select count(*) from tbl where uid=uid and pwd=pwd;
 5 
 6             string uid = txtUid.Text.Trim();
 7             string pwd = txtPwd.Text;
 8 
 9             // 验证 。。。
10 
11             string connStr = ConfigurationManager.ConnectionStrings["sql"].ConnectionString;
12 
13             string sql = "select count(*) from LoginTestWithPrimary where uid=‘" + uid + "‘ and pwd=‘" + pwd + "‘;";
14             int count;
15             using (SqlConnection conn = new SqlConnection(connStr))
16             {
17                 // 执行对象
18                 using (SqlCommand cmd = new SqlCommand(sql, conn))
19                 {
20                     conn.Open();
21                     count = (int)cmd.ExecuteScalar();
22                 }
23             }
24             if (count > 0)
25             {
26                 MessageBox.Show("登陆成功");
27             }
28             else
29             {
30                 MessageBox.Show("用户名或密码错误");
31 
32             }
33         }

      这样的话在密码端输入框中输入1’ or ‘1’=‘1,无论我们输入什么账户名,都会弹出登录成功MessageBox.

      以此我们可以做出以下改动:

 1 string pwd = txtPwd.Text.rePlace("\‘","\‘\‘"); 

     我们也可以做出以下的调整,对Sql语句进行参数化查询,所谓的参数化就是就是将需要值的地方,用一个参数变量进行描述,也就是进行参数的替换。

 1     string sql = "select count(*) from LoginTestWithPrimary where uid=@uid123 and pwd=@pwd;";//sql查询语句
 2 
 3             // 参数赋值
 4             SqlParameter pUid = new SqlParameter("@uid123", uid);
 5             SqlParameter pPwd = new SqlParameter("@pwd", pwd);
 6             
 7             // 
 8             int count;
 9             using (SqlConnection conn = new SqlConnection(connStr))
10             {
11                 using (SqlCommand cmd = new SqlCommand(sql, conn))
12                 {
13                     // 3 将参数交给cmd
14                     cmd.Parameters.Add(pUid);
15                     cmd.Parameters.Add(pPwd);
16 
17 
18                     conn.Open();
19                     count = (int)cmd.ExecuteScalar();
20                 }
21             }
22 
23             if (count > 0)
24             {
25                 Console.WriteLine("登陆成功");
26             }
27             else
28             {
29                 Console.WriteLine("登陆失败");
30             }

   

 

 3、结论分析

     因为1=1永远是都是成立的,即where子句总是为真,将该sql进一步简化之后,等价于如下select语句: select count(*) from LoginTestWithPrimary where uid=‘123‘ and pwd=‘1‘ or ‘1‘=‘1‘。没错,该sql语句的作用是检索LoginTestWithPrimary 表中的所有字段的受影响的行数,从这条语句上看无论uid和pwd是什么,进行的或运算,结果都为真。

      在使用参数化查询的情况下,数据库服务器不会将参数的内容视为sql指令的一部份来处理,而是在数据库完成sql指令的编译后,才套用参数运行,因此就算参数中含有指令,也不会被数据库运行。Access、SQL Server、MySQL、SQLite等常用数据库都支持参数化查询。这样也易形成一个规范去使用sql去操作,避免注入漏洞的问题的发生。 

浅谈注入漏洞问题

标签:

原文地址:http://www.cnblogs.com/fuGuy/p/5666423.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!