Sqlparameter防SQL注入

自作多情 提交于 2020-02-27 05:14:27

 

一、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注入的问题值得我们注意的还有很多,还有待于我们慢慢的积累。
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!