Sqlparameter防SQL注入

 

一、SQL注入的原因

 

         随着B/S模式应用开发的发展,使用这种模式编写应用程序的程序员也越来越多。但是由于这个行业的入门门槛不高,程序员的水平及经验也参差不齐,相当大一部分程序员在编写代码的时候,没有对用户输入数据的合法性进行判断,使应用程序存在安全隐患。用户可以提交一段数据库查询代码,根据程序返回的结果,获得某些他想得知的数据,这就是所谓的SQL Injection,即SQL注入。 

        SQL注入是从正常的WWW端口访问,而且表面看起来跟一般的Web页面访问没什么区别,所以目前市面的防火墙都不会对SQL注入发出警报,如果管理员没查看IIS日志的习惯,可能被入侵很长时间都不会发觉。  

但是,SQL注入的手法相当灵活,在注入的时候会碰到很多意外的情况。能不能根据具体情况进行分析,构造巧妙的SQL语句,从而成功获取想要的数据,是高手与“菜鸟”的根本区别。
 

二、SQL注入的一般步骤


首先,判断环境,寻找注入点,判断数据库类型。

其次,根据注入参数类型,在脑海中重构SQL语句的原貌,按参数类型主要分为下面三种: 

(A) ID=49 这类注入的参数是数字型,SQL语句原貌大致如下: 

Select * from 表名 where 字段=49 

注入的参数为ID=49 And [查询条件],即是生成语句: 

Select * from 表名 where 字段=49 And [查询条件] 

(B) Class=连续剧 这类注入的参数是字符型,SQL语句原貌大致概如下: 

Select * from 表名 where 字段=’连续剧’ 

注入的参数为Class=连续剧’ and [查询条件] and ‘’=’ ,即是生成语句: 

Select * from 表名 where 字段=’连续剧’ and [查询条件] and ‘’=’’ 

(C) 搜索时没过滤参数的,如keyword=关键字,SQL语句原貌大致如下: 

Select * from 表名 where 字段like ’%关键字%’ 

注入的参数为keyword=’ and [查询条件] and ‘%25’=’, 即是生成语句: 

Select * from 表名 where字段like ’%’ and [查询条件] and ‘%’=’%’ 

接着,将查询条件替换成SQL语句,猜解表名,例如: 

ID=49 And (Select Count(*) from Admin)>=0 

         如果页面就与ID=49的相同,说明附加条件成立,即表Admin存在,反之,即不存在(请牢记这种方法)。如此循环,直至猜到表名为止。 表名猜出来后,将Count(*)替换成Count(字段名),用同样的原理猜解字段名。 

         有人会说:这里有一些偶然的成分,如果表名起得很复杂没规律的,那根本就没得玩下去了。说得很对,这世界根本就不存在100%成功的黑客技术,苍蝇不叮无缝的蛋,无论多技术多高深的黑客,都是因为别人的程序写得不严密或使用者保密意识不够,才有得下手。 

 

三、防范方法

          SQL注入漏洞可谓是千里之堤,溃于蚁穴,这种漏洞在网上极为普遍,通常是由于程序员对注入不了解,或者程序过滤不严格,或者某个参数忘记检查导致。在这里,我给大家一个函数,代替ASP中的Request函数,可以对一切的SQL注入说 NO

下面我就说说用SqlParameterSQL注入的方法 

1、 SqlParameter 构造函数

SqlParameter(String, SqlDbType, Int32,ParameterDirection, Byte, Byte, String, DataRowVersion, Boolean, Object,String, String, String),其参数分别代表该类使用参数名、参数的类型、参数的长度、方向、精度、小数位数、源列名称、DataRowVersion 值之一、用于源列映射的布尔值、SqlParameter 的值、此 XML 实例的架构集合所在的数据库的名称、此 XML 实例的架构集合所在的关系架构以及此参数的架构集合的名称。

2、  SqlParameter的应用

 

Public Class UserDAL

    ''' <summary>

    ''' 查询用户信息

    ''' </summary>

    ''' <param name="enUserInfo"></param>

    ''' <returns>UserOne</returns>

    ''' <remarks>返回用户的基本信息实体</remarks>

    Public Function Inquiry(ByVal enUserInfo As Entity.UserInfoEntity) As Entity.UserInfoEntity

        '定义UserInfoEntity的一个对象

        Dim UserOne As New Entity.UserInfoEntity

        '获得连接字符串

         Dim strConnection As String = System.Configuration.ConfigurationManager.AppSettings("sqlConnectStr")

        '设置连接

        Dim conn As SqlConnection = New SqlConnection(strConnection)

        '定义命令对象

        Dim cmd As New SqlCommand

        '定义一个适配器对象

        Dim sqlAdapter As SqlDataAdapter

        '实例一个数据表的对象

        Dim dt As New DataTable

        '实例一个数据集的对象

        Dim ds As New DataSet

        'sal语句

        Dim strSql As String = "select *from T_UserInfo where UserNO=@UserNo"

        Dim paras As SqlParameter() = {New SqlParameter("@UserNo", enUserInfo.UserNo)}



        '对cmd进行赋值

        cmd.CommandText = strSql

        cmd.CommandType = CommandType.Text

        cmd.Connection = conn

        cmd.Parameters.AddRange(paras)

        sqlAdapter = New SqlDataAdapter(cmd)





        conn.Open()            '打开连接

        sqlAdapter.Fill(ds)    '填充数据集

        dt = ds.Tables(0)

        cmd.Parameters.Clear()

        conn.Close()

        cmd.Dispose()



        Try

            '对实体进行赋值

            UserOne.UserNo = dt.Rows(0).Item("UserNO")

            UserOne.UserName = dt.Rows(0).Item("UserName")

            UserOne.UserLevel = dt.Rows(0).Item("UserLevel")

            UserOne.UserPwd = dt.Rows(0).Item("UserPWD")

            UserOne.RegisterManager = dt.Rows(0).Item("RegisterManager")

            Return UserOne

        Catch ex As Exception

            Return UserOne

        End Try



    End Function



 

3、 SqlParameter的基本原理是执行计划重用。即对注入后的SQL语句重新进行了编译,重新执行了语法解析。

四、总结

    不管怎么说,在今后的开发中,对于SQL注入的问题值得我们注意的还有很多,还有待于我们慢慢的积累。

你可能感兴趣的:(parameter)