原创 操作数据库的三种途径收藏

 | 旧一篇: ADO.NET中的职责分配

  

操作数据库可以分这么三种,第一种,直接写硬SQL代码,不要参数,第二种,直接写硬代码,要参数,第三种,调用存储过程。

我们以一个登录模块为例,现在页面有两文本框,一按纽,实现验证用户名密码的功能。第一种方法主要代码如下:

                 SqlConnection conn =new  SqlConnection                    ("server=;database=news2;uid=sa;pwd=");
            conn.Open();
             SqlCommand cmd=new SqlCommand();
             cmd.CommandText="select count(*)from users where name='"+this.TextBox1.Text+"'and pwd='"+this.TextBox2.Text+"'";
               cmd.Connection=conn;
               int i=(int)cmd.ExecuteScalar();
              Response.Write(i.ToString());

 if(i==1)

 {

 Response.Redirect("add.aspx");}

        else

 {

      Label1.Text="error!"

        }

第二种途径

SqlConnection conn =new  SqlConnection("server=;database=news;uid=sa;pwd=");

 conn.Open();//打开数据库

SqlCommand cmd=new SqlCommand();//建立命令对象

   cmd.CommandText="select count(*)from users where name=@name and pwd=@pwd";

   cmd.Connection=conn;//设置连接

    SqlParameter p= new SqlParameter("@name",SqlDbType.Char,10);

//定义参数

   p.Value=this.TextBox1.Text;

     cmd.Parameters.Add(p);//添加参数到集合

     p= new SqlParameter("@pwd",SqlDbType.Char,10);

 p.Value=this.TextBox2.Text;

  cmd.Parameters.Add(p);

      int i=(int)cmd.ExecuteScalar();

       if(i==1)

         {

               Response.Redirect("add.aspx");}

          else

         {

                Label1.Text="error!"

                }

第三种途径

SqlConnection conn =new  SqlConnection("server=;database=news;uid=sa;pwd=");

                    conn.Open();//打开数据库

                    SqlCommand cmd=new SqlCommand();//建立命令对象

                            cmd.CommandText=" checkLogin";//设置命令文本

                    cmd.CommandType=CommandType.StoredProcedure;

//设置文本类型

                    cmd.Connection=conn;//设置连接

                    SqlParameter p= new SqlParameter("@name",SqlDbType.Char,10);

//定义参数

                    p.Value=this.TextBox1.Text;

                    cmd.Parameters.Add(p);//添加参数到集合

                    p= new SqlParameter("@pwd",SqlDbType.Char,10);

                    p.Value=this.TextBox2.Text;

                    cmd.Parameters.Add(p);

                    int i=(int)cmd.ExecuteScalar();

                    if(i==1)

                    {

                           Response.Redirect("add.aspx");}

                    else

                    {

                           Label1.Text="error!"

                            }

接下来对这三种方法做分析

第一方法不能防范SQL注入式方式攻击,比如在第一个文本框输入asd'or's'='s  第二个同样输入asd'or's'='s ,可以发现成功通过验证。

第二种直接写硬SQL代码,事实上不是每个人都能写出优良的SQL代码来,可以由数据库管理员或工程师来写,这样,一方面减轻程序员的工作,另一方面也可以使数据库与应用程序保持独立,这样有利于系统的移植与维护。

当然第三种是推荐使用的,好处呢,就是前面所写的。

发表于 @ 2007年10月30日 01:51:00|评论(loading...)|编辑

 | 旧一篇: ADO.NET中的职责分配

评论

#zjh222 发表于2007-10-30 10:58:19  IP: 222.212.158.*
string.Format(....)的方式也能防注入吗/?
#mndn_nana 发表于2007-10-30 11:37:39  IP: 221.204.190.*
第一方法不能防范SQL注入式方式攻击,比如在第一个文本框输入asd'or's'='s 第二个同样输入asd'or's'='s ,可以发现成功通过验证。
???为什么这样就能验证成功呢?
#heshou5 发表于2007-10-30 12:11:07  IP: 59.107.115.*
string.Format(....)的方式也能防注入吗/?
不能防范。
#heshou5 发表于2007-10-30 12:13:34  IP: 59.107.115.*
第一方法不能防范SQL注入式方式攻击,比如在第一个文本框输入asd'or's'='s 第二个同样输入asd'or's'='s ,可以发现成功通过验证。
???为什么这样就能验证成功呢?

你看这条SQL语句
select count(*)from users where name='asd'or's'='s' and pwd='asd'or's'='s '
后面的条件是永真的
#heshou5 发表于2007-10-30 12:29:08  IP: 59.107.115.*
大家可以亲自试一下,建立表的SQL 如下
create database news
use news
/建立表
create table users(id int identity ,name char(10),pwd char(10))
go

create proc insertUser
@name char(10)
@pwd char(10)
as
insert into users values(@name,@pwd)
go

create proc checkLogin
@name char(4),@pwd char(10)
as
select * from userinfro where name=@name and pwd=@pwd
return @@error
go

exec insertUser admin,123456
#mndn_nana 发表于2007-10-30 15:56:41  IP: 221.204.190.*
道理是明白了,但
exec checkLogin 'asd'or's'='s','asd'or's'='s' 执行create proc checkLogin
@name char(4),@pwd char(10)
as
select * from userinfro where name=@name and pwd=@pwd
return @@error
go后,报错在关键字 'or' 附近有语法错误。
请问是什么情况啊?
#mndn_nana 发表于2007-10-30 15:57:58  IP: 221.204.190.*
"在关键字 'or' 附近有语法错误。"
就是上面这句提示的问题
#cozo 发表于2007-10-30 17:17:38  IP: 58.246.58.*
但是我的一个select count的命令最后where里面是一个日期字段,取一段时间内的条数,如果用第一种方法把时间拼进SQL里面去,就能执行通过,用第二种方法,把时间传参数进去,就会执行超时。
#heshou5 发表于2007-10-30 19:56:53  IP: 59.107.115.*
"在关键字 'or' 附近有语法错误。"
就是上面这句提示的问题
存储过程是可以防范注入式攻击的,他把OR当作关键字了
另外 @name char(4)打错了,应该为@name char(10),呵呵,不好意思
#heshou5 发表于2007-10-30 19:58:19  IP: 59.107.115.*
但是我的一个select count的命令最后where里面是一个日期字段,取一段时间内的条数,如果用第一种方法把时间拼进SQL里面去,就能执行通过,用第二种方法,把时间传参数进去,就会执行超时。
把具体的代码贴出来看看
#mndn_nana 发表于2007-10-30 20:34:45  IP: 221.205.225.*
也就是说,第一种,直接写硬SQL代码,不要参数 这样文本框中的表达式'asd'or's'='s '先执行,以至于会cmd.CommandText="select count(*)from users where name='"+this.TextBox1.Text+"'and pwd='"+this.TextBox2.Text+"'";
变成了name=1 and pwd=1
然后成了where 1 也就是"真值" 导致了不为0
造成了最后的'SQL注入式方式攻击'效果

而第二种,直接写硬代码,要参数和第三种,调用存储过程
正是由于把"OR"当作了关键字,报错"在关键字 'or' 附近有语法错误。"而避免了注入式方式攻击

原理清楚了,偶再具体敲以一下
谢谢LZ~ 希望今后能看到LZ更多的原创文章

发表评论  


当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
Csdn Blog version 3.1a
Copyright © heshou5