(二)SQL 注入

SQL注入就不用介绍了,网上很多。下面介绍一下防止SQL注入的方法。

使用quotename 函数和 sp_executesql

参考如下表结构:这是一个文档表里面有一些简单的字段信息

CREATE TABLE [dbo].[DocumentInfo](

    [ID] [int] IDENTITY(1,1) primary key  NOT NULL,--主键

    [Name] [varchar](100) NOT NULL,--文档名字

    [FunctionID] [int] NOT NULL--功能ID外键

    [TypeInfo] [nvarchar](2000) NULL—描述信息

我们可能会按,主键ID,文档的名字,功能id 描述信息进行查询 ,这个一看就是拼接sql语句,如果不用上面的方法很可能造成sql注入

例如你写的存储过程可能如下:

CREATE proc [dbo].[Doc_search]

(

@ID int,

@name varchar(10),

@FID int,

@Info nvarchar(20)

)

as

begin

declare @sql varchar(300)

set @sql='select * from [DocumentInfo] where 1=1'

if @ID<>-1

set @sql=@sql+' and ID='+CAST(@ID as varchar)

if @name<>''

set @sql=@sql+' and name='''+CAST(@name as varchar) +''''

if @FID<>-1

set @sql=@sql+' and [FunctionID]='+CAST(@FID as varchar)

if @Info <>''

set @sql=@sql+ ' and [TypeInfo] like ''%'+CAST(@Info as varchar)+'%'''

print @sql

end

exec(@sql)

虽然你用了带参数的存储过程 ,但本质上还是拼接字符串,没有有效的防治sql注入。现在分别用quotename()函数和sp_executesqlQuotename()函数不知道用的请自行查找,sp_executesql的用法见上一篇动态sql

Quotename改进如下:

alter proc [dbo].[Doc_search]

(

@ID int,

@name varchar(10),

@FID int,

@Info nvarchar(20)

)

as

begin

declare @sql varchar(300)

set @sql='select * from [DocumentInfo] where 1=1'

if @ID<>-1

set @sql=@sql+' and ID='+CAST(@ID as varchar)

if @name<>''

set @sql=@sql+' and name='+QUOTENAME(@name,'''')

if @FID<>-1

set @sql=@sql+' and [FunctionID]='+CAST(@FID as varchar)

if @Info <>''

set @Info='%'+@Info+'%';

set @sql=@sql+ ' and [TypeInfo] like '+QUOTENAME(@Info,'''')

print @sql

end

exec(@sql)

但这种方法碰到字段是Int类型的就会失效

所以推荐使用sp_executesql 改进存储过程如下:

alter proc [dbo].[Doc_search]

(

@ID int,

@name varchar(10),

@FID int,

@Info nvarchar(20)

)

as

begin

declare @sql nvarchar(300)

set @sql=N'select * from [DocumentInfo] where 1=1'

if @ID<>-1

set @sql=@sql+' and ID=@ID'

if @name<>''

set @sql=@sql+' and name=@name'

if @FID<>-1

set @sql=@sql+' and [FunctionID]=@FID'

if @Info <>''

set @Info='%'+@Info+'%';

set @sql=@sql+ ' and [TypeInfo] like @Info'

print @sql

end

exec sp_executesql @sql ,N'@ID as int,@name as varchar(10),@FID as int,@Info as nvarchar(20)',@ID,@Name ,@FID,@Info

这样参数化才是真的参数化 注意like的用法。用’’Sql注入第一种 然后再注入第三种会发现得不到你想要的结果。sp_executesql 还是非常有用的 下一篇介绍 sp_executesql 怎样实现比较通用的分页存储过程

posted @ 2010-05-13 18:01  清水无大大鱼  阅读(1967)  评论(0编辑  收藏  举报