• (二)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 怎样实现比较通用的分页存储过程


    作 者:清水无鱼
    出 处:http://www.cnblogs.com/wzpo/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面 明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    http://www.bugku.com:Bugku——SQL注入1(http://103.238.227.13:10087/)
    [笔记]一道C语言面试题:大整数乘法
    [笔记] Access Control Lists (ACL) 学习笔记汇总
    [笔记]如何将传统的回调函数转换为C#5.0支持的await格式
    6.链接与导航
    9章 下拉菜单
    11章圆角框 本章很重要 经常用到
    原来链接与导航
    7竖直排列的导航菜单
    8.水平导航菜单
  • 原文地址:https://www.cnblogs.com/wzpo/p/1734771.html
Copyright © 2020-2023  润新知