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_executesql Quotename()函数不知道用的请自行查找, 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 怎样实现比较通用的分页存储过程

 

转自:http://www.cnblogs.com/wzpo/archive/2010/05/13/1734771.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值