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