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

發佈了56 篇原創文章 · 獲贊 6 · 訪問量 23萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章