Sql parameter防SQL注入

  1. <h1><a name=”t0″></a><span style=”font-family:KaiTi_GB2312;font-size:18px;font-weight: normal;”>一、SQL注入的原因</span></h1><span style=”font-family:KaiTi_GB2312;”>
  2. </span>

 

随着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。

下面我就说说用SqlParameter防SQL注入的方法

1、 SqlParameter 构造函数

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

2、  SqlParameter的应用

 

[plain][/plain] view plaincopy

  1. <span style=”font-family:KaiTi_GB2312;font-size:14px;”>Public Class UserDAL
  2.     ”’ <summary>
  3.     ”’ 查询用户信息
  4.     ”’ </summary>
  5.     ”’ <param name=”enUserInfo”></param>
  6.     ”’ <returns>UserOne</returns>
  7.     ”’ <remarks>返回用户的基本信息实体</remarks>
  8.     Public Function Inquiry(ByVal enUserInfo As Entity.UserInfoEntity) As Entity.UserInfoEntity
  9.         ‘定义UserInfoEntity的一个对象
  10.         Dim UserOne As New Entity.UserInfoEntity
  11.         ‘获得连接字符串
  12.          Dim strConnection As String = System.Configuration.ConfigurationManager.AppSettings(“sqlConnectStr”)
  13.         ‘设置连接
  14.         Dim conn As SqlConnection = New SqlConnection(strConnection)
  15.         ‘定义命令对象
  16.         Dim cmd As New SqlCommand
  17.         ‘定义一个适配器对象
  18.         Dim sqlAdapter As SqlDataAdapter
  19.         ‘实例一个数据表的对象
  20.         Dim dt As New DataTable
  21.         ‘实例一个数据集的对象
  22.         Dim ds As New DataSet
  23.         ‘sal语句
  24.         Dim strSql As String = “select *from T_UserInfo where UserNO=@UserNo”
  25.         Dim paras As SqlParameter() = {New SqlParameter(“@UserNo”, enUserInfo.UserNo)}
  26.         ‘对cmd进行赋值
  27.         cmd.CommandText = strSql
  28.         cmd.CommandType = CommandType.Text
  29.         cmd.Connection = conn
  30.         cmd.Parameters.AddRange(paras)
  31.         sqlAdapter = New SqlDataAdapter(cmd)
  32.         conn.Open()            ‘打开连接
  33.         sqlAdapter.Fill(ds)    ‘填充数据集
  34.         dt = ds.Tables(0)
  35.         cmd.Parameters.Clear()
  36.         conn.Close()
  37.         cmd.Dispose()
  38.         Try
  39.             ‘对实体进行赋值
  40.             UserOne.UserNo = dt.Rows(0).Item(“UserNO”)
  41.             UserOne.UserName = dt.Rows(0).Item(“UserName”)
  42.             UserOne.UserLevel = dt.Rows(0).Item(“UserLevel”)
  43.             UserOne.UserPwd = dt.Rows(0).Item(“UserPWD”)
  44.             UserOne.RegisterManager = dt.Rows(0).Item(“RegisterManager”)
  45.             Return UserOne
  46.         Catch ex As Exception
  47.             Return UserOne
  48.         End Try
  49.     End Function</span>

 

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

四、总结

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

标签