A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 张少甫 中级黑马   /  2013-2-24 11:00  /  1542 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

什么是sql注入,怎么防止防止sql注入。最好是有代码说明.谢谢

2 个回复

倒序浏览
sql注入就是将一个条件变成了多个条件

假设数据库中有个用户名 admin    密码 123456  

string uid = "admin" ;   string pwd = "123456";   --------  正常的是要这样才能正确登录的.  
在sql中的语句是: select conut(*) from database where uid='admin' and pwd='123456' 。

但是如果把密码改成   string pwd = "123' or '1' = '1";

在数据库的语句就成了  :    select count(*) from database where uid = 'admin' and pwd = '123' or '1' = '1'    ----因为后面有个 or '1'='1' 所以这个条件永远成立,即使密码错误也可以登录,甚至用户名错了都可以。高手们可以根据这个漏洞来测试你服务器的一些东西,具体我也不懂了。。

防止sql注入的办法就是参数化.下面上代码

            // -> 在需要使用拼接的地方用@引导一个别名(变量)
            // -> 创建SqlParameter对象,为别名赋值
            //      通过构造函数
            // -> 在执行SQL语句的时候,为cmd添加参数
            string sql = "select count(*) from database where uid=@uid and pwd=@pwd";

            SqlParameter uid = new SqlParameter("@uid", txtUid.Text.Trim());
            SqlParameter pwd = new SqlParameter("@pwd", txtPwd.Text);


            using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["sql"].ConnectionString))
            {
                using (SqlCommand cmd = new SqlCommand(sql, conn))
                {
                    // 添加参数
                    cmd.Parameters.Add(uid);
                    cmd.Parameters.Add(pwd);

                    conn.Open();
                    int res = Convert.ToInt32(cmd.ExecuteScalar());
                    if (res > 0)
                    {
                        MessageBox.Show("登录成功");
                    }
                    else
                    {
                        MessageBox.Show("Error");
                    }
                }
            }
回复 使用道具 举报
SQL注入是最有效,也是最常见的一种攻击方式,70%以上的网站存在SQL Injection 漏洞
SQL注入攻击的方法千变万化,并且不被浏览器拦截,这是他的可怕之处,我说两个最基础的,说明下原理就行【这种方法现在也是用不了的,能用的也不敢在这说哈】
可能语言不同,但是技术都是相同的,只供理解

1.当sql语句这么写的时候     $sql="select * from user where username='$username' and password='$password'";
可以用万能用户名登录后台管理界面(密码随便输,下同)    万能用户名:   xx' union select & from users /*
同样,也有万能密码           万能密码:   aa' or 1='1
2.1.当sql语句这么写的时候     $sql="select * from user where username=$username and password=$password";   【没有单引号,mysql会把你的输入当数字对待】
万能用户名:    数字 union select * from users/*
万能密码:  数字 union select * from uesrs;   【用户名一定输成数字】

解决方法:
1.更改服务器配置,方法暂且不说,因为服务器不一样方法也肯定不一样,更改配置让服务器对所有的  ' 加入 \ 转义
   比如 name='123'     当数据库执行时为    name=\'123\'
   用这种方法只能解决上面的第一种方法,第二种方法依然有效,并且在第一种情况下,高手也可以用char(96)代替 ' 测试
2.密码比对
   首先通过用户输入的用户名去查询数据库,如果查到这个用户对应的密码,则和用户提交的密码比对,相同则说明该用户合法,反之非法,
   具体实现方法更具语言不同写法也不同,各自参考
3.C#中的ADO,java中的JDBC, php中的PDO。都对数据库有预处理操作,这种操作可以很好的防止sql注入攻击,具体方法根据自己学习的语言不同各自实现
4.还有查询sql攻击就不多说了,利用敏感符号对所需要的信息的查询,对关键字进行过滤【加入\转义】就能防止这种查询攻击  比如将 % 换成 \%   将__ 换成\__   ....之类的
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马