黑马程序员 c#学习10

Windows Phone 7手机开发.Net培训、期待与您交流! 1、参数化查询


   前面使用的查询语句可能会引起sql注入攻击,所谓sql注入攻击,就是用户在输入数据时构造一条sql语句,让查询顺利进行,取消了任何验证逻辑。我们拿登陆程序来试验下。


   对于一个登陆模块,通常我们要求用户输入用户名和密码,然后提交到数据库进行验证,


   我们假设用户名 为admin  密码为 888888


   登陆界面  txtUserName文本框是用户名,passwordBox是用户密码。


   当我们输入用户名和密码时,普通情况下我们是通过构造一个查询字符串提交到数据库来验证是否匹配


            string userName = txtUserName.Text;  //取得用户输入的用户名
            string password = passwordBox.Password; //取得用户输入与的密码
            using ( SqlConnection conn = new SqlConnection ( "Data Source=.;Initial Catalog=test;User ID=sa;Password=123456" ) )//创建连接对象
            {
                conn.Open ( );   //打开连接对象
                using ( SqlCommand cmd = new SqlCommand ( ) )//创建命令对象
                {
                    
                    cmd.CommandText = "select count(*) from T_user where name = " + "'"+userName+ "'" +"and password =" + "'"+password+"'"; //构造sql语句
                    cmd.Connection = conn;
                    {
                        MessageBox.Show ( "登陆成功" );
                    }
                    else
                    {
                        MessageBox.Show ( "登陆失败" );
                    }


                    
                }
            }


        这样,当我们输入正确的用户名和密码时,会提示和登陆正确 ,但是我们来看我们的sql语句


        select count(*) from T_user where name = " + "'"+userName+ "'" +"and password =" + "'"+password+"'"
      
         当我们在用户名中输入admin时,在密码框中输入以下字符串1 ' or '1'='1 看看我们构造出来的语句是什么


         select count(*) from T_user where name = ‘admin' and password = '1' or '1'='1'
  
         这个sql语句一定是成功的,因为'1'='1'始终是成立的,这样,我们通过一些特殊的输入通过了密码的验证。这就是sql注入攻击。


    解决这个问题,我们就需要使用参数化查询


    
          string userName = txtUserName.Text;
            string password = passwordBox.Password;
            using ( SqlConnection conn = new SqlConnection ( "Data Source=.;Initial Catalog=test;User ID=sa;Password=123456" ) )
            {
                conn.Open ( );
                using ( SqlCommand cmd = new SqlCommand ( ) )
                {
                    
                    cmd.CommandText = "select count(*) from T_user where name = @un and password = @ps";
                    cmd.Parameters.Add(new SqlParameter("@un",userName));
                    cmd.Parameters.Add(new SqlParameter("@ps",password));
                    cmd.Connection = conn;
                    if ( (int)cmd.ExecuteScalar ( ) != 0  )
                    {
                        MessageBox.Show ( "登陆成功" );
                    }
                    else
                    {
                        MessageBox.Show ( "登陆失败" );
                    }
                   
                }
            }
        看看我们的sql语句,我们使用了@un 和@ps两个参数来代替大量的字符串连接,@表示这是一个参数


         cmd.Parameters.Add(new SqlParameter("@un",userName));
         cmd.Parameters.Add(new SqlParameter("@ps",password));
         这两条语句用来给参数赋值,new SqlParameter("@un",userName) 这个构造函数的第一个参数指定参数名称,注意,这个名称一定要和我们的sql语句中的参数名称相对应,第二个参数就是我们要给参数的值,
         这样即使我们使用 1 ' or '1'='1这样的密码,也不能通过验证,


      从上面的例子可以看出,sql注入攻击的本质是通过引号之间的就近配对来修改我们的sql语句的结构,灵活的使用''和and or等逻辑字符,构造出一个总能成功执行的sql语句。参数化查询则避免了这种情况。


      另外,参数化查询的语句结构也更容易让人看明白,出错后也较容易调试,而字符串拼接出错后不容易调试,也容易出错,所以建议使用参数化查询。 Windows Phone 7手机开发.Net培训、期待与您交流!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值