首页 | 公司简介 | 数据恢复 | 成功案例 | 技术中心 | 客户服务 | 服务报价 | 联系我们 | 技术论坛  
 
  北京总部: 4006-505-808
  上 海 部: 021-58358765
  深 圳 部: 0755-83692929
  浙 江 部: 13666673722
  广 州 部: 020-62683398
  重 庆 部: 023-86870422
  福 建 部: 0591-83300680
  西 安 部: 029-68614669
  其它地区: 4006-505-808

中国联通信息平台-HP-UX数据恢
中国石油管理局-Oracle数据库恢
工商银行山东分行-AIX删除LV数
濮阳市地方税务局-CHKDSK后数据
台湾HD公司-FreeBSD Nas无法启
promise乔鼎硬盘阵列数据恢复成
IBM EXP300 磁盘阵列数据恢复成
NAS 8100无法挂载数据卷

LINUX FSCK数据出错灾难应急方
误删除、误格式化数据灾难应急
误GHOST、误一键恢复灾难应急方
 磁盘未被格式化,是否格式化数
raid磁盘阵列OFFLINE后的应急方
硬盘出现异响应急处理
您当前的位置:首页 >> 安全常识 >> 正文

如此高效通用的分页存储过程是带有sql注入漏洞的

在google中搜索“分页存储过程”会出来好多结果,是大家常用的分页存储过程,今天我却要说它是有漏洞的,而且漏洞无法通过修改存储过程进行补救,如果你觉得我错了,请读下去也许你会改变看法。

通常大家都会认为存储过程可以避免sql注入的漏洞,这适用于一般的存储过程,而对于通用分页存储过程是不适合的,请看下面的代码和分析!

一般的通用的分页存储过程代码如下:

通用分页存储过程
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 @strSQL varchar(5000) -- 主语句
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

else
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

else
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模糊查询用户,为了叙述方便,便于理解我们只考虑取第一页的情况,取出存储过程中取第一页的拼串行如下:

set @strSQL = 'SELECT TOP ' + str(@PageSize) + ' ' + @strGetFields + ' from [' + @tblName + ']  where ' + @strWhere + ' ' + @strOrder
 
为了便于说明问题,我们可以假定@pageSize为20,@strGetFields为 ‘*’,@tblName为UserAccount,@strOrder为’ ORDER  BY  ID DESC’ 那么上面一行可以写成如下形式:

本新闻共2页,当前在第1页  1  2  

上一篇:使用磁盘阵列时应注意什么?
下一篇:MySQL数据库中关于网络安全的解决方案
返回首页 | 联系我们 | 关于我们 | 招聘信息 | 友情链接 | 网站地图 | 合作伙伴
版权所有 北京北亚数据恢复中心
24小时免费咨询电话:4006-505-808 或 800-810-5880
公司地址:北京市海淀区学院南路68号吉安大厦C座(汇智楼)528室
京ICP备07502730