在google中搜索“分页存储过程”会出来好多结果,是大家常用的分页存储过程,今天我却要说它是有漏洞的,而且漏洞无法通过修改存储过程进行补救,如果你觉得我错了,请读下去也许你会改变看法。 通常大家都会认为存储过程可以避免sql注入的漏洞,这适用于一般的存储过程,而对于通用分页存储过程是不适合的,请看下面的代码和分析! 一般的通用的分页存储过程代码如下: 通用分页存储过程 declare @strSQL varchar(5000) — 主语句 else else set @strSQL = SELECT TOP + str(@PageSize) + + @strGetFields + from [ + @tblName + ] where + @strWhere + + @strOrder set @strSQL = SELECT TOP 20 * from [UserAccount] where + @strWhere + ORDER BY ID DESC’ 我们用SqlParameter传递参数给分页存储过程@strWhere 的值是:’UserName LIKE ‘’%Jim’’ dog%’’’(注意LIKE后边的字符串中的单引号已经全部变成两个单引号了),我们将这个值代入上面的@strSQL赋值语句中,如下: set @strSQL = SELECT TOP 20 * from [UserAccount] where UserName LIKE %Jim dog% ORDER BY ID DESC’ DECLARE @strSQL varchar(8000) 大家可以把上面几行代码粘贴到查询分析器中执行一下,就可以看到下面的画面: 1.很显然我们使用SqlParameter传递参数已经将单引号替换成了连个单引号了,可是因为我们在数据库中拼串导致替换并不能解决问题。 2.根据我的实验证明如果使用存储过程不可能解决这个问题,我们只有将这个存储过程要执行的拼串操作放到数据访问层去做,才可以避免这个问题。 如果大家有在存储过程中解决这个问题的办法,请不吝赐教。 备注:本文说的是MS SQL Server2000 的数据库,而非使用SQL 2005的新特性分页。 http://www.cnblogs.com/yukaizhao/archive/2007/03/09/pagination_proc_problem.html
CREATE PROCEDURE pagination
@tblName varchar(255), — 表名
@strGetFields varchar(1000) = *, — 需要返回的列
@fldName varchar(255)=, — 排序的字段名
@PageSize int = 10, — 页尺寸
@PageIndex int = 1, — 页码
@doCount bit = 0, — 返回记录总数, 非 0 值则返回
@OrderType bit = 0, — 设置排序类型, 非 0 值则降序
@strWhere varchar(1500) = — 查询条件 (注意: 不要加 where)
AS
declare @strTmp varchar(110) — 临时变量
declare @strOrder varchar(400) — 排序类型
if @doCount != 0
begin
if @strWhere !=
set @strSQL = select count(*) as Total from [ + @tblName + ] where +@strWhere
else
set @strSQL = select count(*) as Total from [ + @tblName + ]
end
–以上代码的意思是如果@doCount传递过来的不是0,就执行总数统计。以下的所有代码都是@doCount为0的情况
— http://www.knowsky.com/article.asp?typeid=20
else
begin
if @OrderType != 0
begin
set @strTmp = <(select min
set @strOrder = order by [ + @fldName +] desc
–如果@OrderType不是0,就执行降序,这句很重要!
end
begin
set @strTmp = >(select max
set @strOrder = order by [ + @fldName +] asc
end
if @PageIndex = 1
begin
if @strWhere !=
set @strSQL = select top + str(@PageSize) + +@strGetFields+ from [ + @tblName + ] where + @strWhere + + @strOrder
else
set @strSQL = select top + str(@PageSize) + +@strGetFields+ from [+ @tblName + ] + @strOrder
–如果是第一页就执行以上代码,这样会加快执行速度
end
begin
–以下代码赋予了@strSQL以真正执行的SQL代码
set @strSQL = select top + str(@PageSize) + +@strGetFields+ from [
+ @tblName + ] where [ + @fldName + ] + @strTmp + ([+ @fldName + ]) from (select top + str((@PageIndex-1)*@PageSize) + [+ @fldName + ] from [ + @tblName + ] + @strOrder + ) as tblTmp)+ @strOrder
if @strWhere !=
set @strSQL = select top + str(@PageSize) + +@strGetFields+ from [
+ @tblName + ] where [ + @fldName + ] + @strTmp + ([
+ @fldName + ]) from (select top + str((@PageIndex-1)*@PageSize) + [
+ @fldName + ] from [ + @tblName + ] where + @strWhere +
+ @strOrder + ) as tblTmp) and + @strWhere + + @strOrder
end
end
exec (@strSQL)
GO
大家可以看到上面的存储过程中是通过一些步骤最终拼接成一个sql字符串,然后通过exec执行这个串得到分页的结果。
我们假定要做一个这样的查询,通过用户名UserName模糊查询用户,为了叙述方便,便于理解我们只考虑取第一页的情况,取出存储过程中取第一页的拼串行如下:
为了便于说明问题,我们可以假定@pageSize为20,@strGetFields为 ‘*’,@tblName为UserAccount,@strOrder为’ ORDER BY ID DESC’ 那么上面一行可以写成如下形式:
我们可以假定用户输入的模糊用户名是: Jim’s dog
让我们写上声明变量的部分执行在查询分析器中测试一下,代码如下:
DECLARE @strWhere varchar(1000)
SET @strWhere = UserName LIKE %Jim dog%
set @strSQL = SELECT TOP 20 * from [UserAccount] where + @strWhere + ORDER BY ID DESC
print @strSQL
exec (@strSQL)
在消息的第一行,打印出了要执行的sql语句,很显然此语句的 LIKE ‘%Jim’ 后面的部分全部被截断了,也就是说如果用户输入的不是Jim’s dog而是Jim’ delete from UserAccount那么会正确的执行删除操作,传说中的sql注入就会出现了。
问题出现了,我们应该怎么解决问题?
如此高效通用的分页存储过程是带有sql注入漏洞的_数据库安全
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » 如此高效通用的分页存储过程是带有sql注入漏洞的_数据库安全
相关推荐
-      鲁大师驱动备份位置在哪里
-      新版360安全卫士怎么样
-      360安全卫士和鲁大师哪个好
-      360安全卫士离线救灾版怎么用
-      360安全卫士把文件删了怎么恢复
-      电脑怎么进入安全模式
-      用U盘去除系统登录密码
-      360安全卫士怎么升级快