通用分页存储过程真的有注入漏洞吗?

揹又寸背拥抱2

揹又寸背拥抱2

2016-02-19 18:18

图老师设计创意栏目是一个分享最好最实用的教程的社区,我们拥有最用心的各种教程,今天就给大家分享通用分页存储过程真的有注入漏洞吗?的教程,热爱PS的朋友们快点看过来吧!

  今天看了两篇关于存储过程SQL注入漏洞的文章:

  1):如此高效通用的分页存储过程是带有sql注入漏洞的

  2):防SQL注入:生成参数化的通用分页查询语句

  怎么看怎么觉的别扭,在我印象中存储过程是不会存在注入漏洞的啊?起码我目前的水平还不了解如何注入存储过程。如果大家有注入的方法请指教。换句话说存储过程本身并无注入漏洞,只不过有漏洞大多都是因为程序漏洞导致。

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)

  我们来简化下之前两位园友讨论的分页存储过程,原代码太长,我这里呢写一个针对一个单表查询的存储过程。创建一个用户表,表结构如下:有三个字段,人员ID,姓名字段。

CREATE TABLE [dbo].[person](
  [id] [int] NULL,
  [last_name] [varchar](30) COLLATE Chinese_PRC_CI_AS NULL,
  [first_name] [varchar](30) COLLATE Chinese_PRC_CI_AS NULL
) ON [PRIMARY]

  然后写一个查询存储过程(getPerson):作用,根据不同的条件读取用户信息。

IF ( EXISTS ( SELECT  *
       FROM   sysobjects
       WHERE   id = OBJECT_ID(N'[dbo].[getPerson]')
            AND OBJECTPROPERTY(id, N'IsProcedure') = 1 ) )
  BEGIN
    DROP PROCEDURE [dbo].[getPerson]
  END
Go
CREATE PROC getPerson
  @strWhere VARCHAR(100) = '' -- 查询条件 (注意: 不要加 where)
AS
  BEGIN
    DECLARE @strSQL VARCHAR(1000) -- 主语句
    SET @strSQL = 'select top 10 * from person where 1=1 '
  --如果存在条件,则加上
    IF @strWhere != ''
      BEGIN
        SET @strSQL = @strSQL + @strWhere     
      END
    PRINT ( @strSQL )
    EXEC ( @strSQL
      )
  END

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)

  查询方式,根据用户的姓来查询。要想最终的存储过程执行语法正确,同时不存在注入漏洞, 此时条件的正确格式是:and first_name like '%Jim''s dog%'。

  我们可以看到条件Jim's dog组装成SQL后,中间的单引号一定要变成两个。为了避免注入,我一般这样处理SQL拼接的安全问题:在C#写程序的时候应该这样写:

/// summary
    /// 屏蔽字符串中的特殊字符
    /// by minjiang 07-07-06
    /// /summary
    public string SafeRequest(string str)
    {
      //定义要返回的字符串
      string sReturn;
      //将要处理的字符串转换为小写字母
      str = str.ToLower();
      //定义特殊字符串
      string SQL_KILL = "'|and|exec|insert|select|delete|update|count|*|%
|chr|mid|master|truncate|char|declare|set|;|from|=|--|drop||";
      char[] separator ={ '|' };
      string[] sql = SQL_KILL.Split(separator);
      for(int i=0;isql .Length ;i++)
      {
        //如果有特殊字符则将它替换成为空
        if(str.IndexOf (sql [i].ToString ().ToLower ())-1)
        {
          //把单引号替换成双引号

if (sql[i].ToString() == "'")
          { str = str.Replace("'", "''"); }
          else
          {
            //把敏感字符替换成空
            str = str.Replace(sql[i].ToString().ToLower(), "");
          }
       
        }
     
      }
      sReturn = str;
      return sReturn;
   
    }
  
if(sUserName!="")
{
 strWhere +=" and first_name like'%"+this.SafeRequest(sUserName)+"%'"
}

  分页存储过程注入的机会: 上面的通用分页存储过程之所以会说存在SQL注入的机会,是因为通配符like后面的单引号,如果在后面参数中也出现单引号与like通配符后面的单引号相匹配后,后面的内容就是SQL注入的内容了。此时我们可以写一个过滤SQL特殊字符的方法,对特殊字符进行处理,可能根据自己的情况,选取相应过滤条件。最起码要把用户名中的单引号替换成双引号。下面的写法是不安全的:用户名中有单引号,例如 :Jim's dog

if(sUserName!="")
{
 strWhere +=" and first_name like'%"+sUserName+"%'"
  
}

  说明:园友 小No提到,能够通过把输入注入条件编码成十六进制编码来骗过过滤程序。这种情况的确存在,所有可以针对html标签中又属于SQL敏感字符的内容进行十六进制的比较。例如:‘,;。“-”不用处理,因为它不会被HTML编码。    

  我个人不太支持这种所谓高效的通用分页存储过程,理由:

  1:可阅读性太差,整版的字符串,谁看着都不舒服。

  2:对应用程序有比较高的安全要求,稍不注意就会存在上面所说的注入漏洞。

  3:对多表的复杂查询无能无力。如果强行应用,我想远比单独写一个存储过程来的麻烦。

  4:所谓通用,即大多数人都知道你这个存储过程的大致结构,这样无疑给别有用心者更多可趁之机。

  针对分页存储过程的处理,不妨看看这篇:你是如何面对大量分页需求的?

  总结:通用分页存储过程本身是没有漏洞可言的,只不过是程序的不严谨造成的注入机会。

  解决这种拼接SQL字符串可能带来的隐患方案:

  1:尽量对输入参数进行类型设置,能设置成数字型的一定要设成数字型。


  2:设置好参数的长度,一个字符串,例如姓名,一般不会超过20个字符。

  3:输入的参数内容能删除空格的就最好利用Trim(),这样,就算有SQL敏感字符,一旦SQL连接成一串,那也是不能够正常注入。

  4:尽量过滤传入的条件,起码要把单引号替换成双引号。

  5:严格设置数据库用户的权限,负责查询的用户,只让它具有读的权限,这样就算是注入成功,也不能造成致命的后果。

  具有插入权限的用户,严格控制删除,更新的权限。而佣有删除权限的用户,一般都佣有查看权限,删除操作是很难存在SQL注入的。

展开更多 50%)
分享

猜你喜欢

通用分页存储过程真的有注入漏洞吗?

编程语言 网络编程
通用分页存储过程真的有注入漏洞吗?

如此高效通用的分页存储过程是带有sql注入漏洞的

编程语言 网络编程
如此高效通用的分页存储过程是带有sql注入漏洞的

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

通用分页存储过程源码共享大家共同完善

编程语言 网络编程
通用分页存储过程源码共享大家共同完善

存储过程分页

ASP
存储过程分页

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

分页存储过程代码

编程语言 网络编程
分页存储过程代码

sql 存储过程分页

Web开发
sql 存储过程分页

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

CSS3系列教程:边框颜色

CSS3系列教程:边框颜色

使用SQL Server 2005 FOR XML嵌套查询

使用SQL Server 2005 FOR XML嵌套查询
下拉加载更多内容 ↓