关于sql注入问题

SQL 注入:

1、SQL 注入是一种攻击方式,在这种攻击方式中,恶意代码被插入到字符串中,然后将该字符串传递到 SQL Server 的实例以进行分析和执行。任何构成 SQL 语句的过程都应进行注入漏洞检查,因为 SQL Server 将执行其接收到的所有语法有效的查询。一个有经验的、坚定的攻击者甚至可以操作参数化数据。

2、SQL 注入的主要形式包括直接将代码插入到与 SQL 命令串联在一起并使其得以执行的用户输入变量。一种间接的攻击会将恶意代码注入要在表中存储或作为元数据存储的字符串。在存储的字符串随后串连到一个动态 SQL 命令中时,将执行该恶意代码。

3、注入过程的工作方式是提前终止文本字符串,然后追加一个新的命令。由于插入的命令可能在执行前追加其他字符串,因此攻击者将用注释标记“--”来终止注入的字符串。执行时,此后的文本将被忽略。

 

如何预防:

这里举3种常见的情况:数字、日期时间、字符串。

1、数字

假设我们要实现一个显示新闻的页面,我们可能会随手写下下面的代码:

string id = Request.QueryString["id"];
string sql = "select * from news where ColID="+ id;

如果传递过来的 id是我们想像的 数字(比如168),那么自然不会有什么问题。但是如果传递过来的id是“168 delete from table ”的话,那么sql的值就变成了“select * from table where ColID=168 delete from news”。对于SQL Server来说是支持一次提交多条SQL语句的,这个为我们提供了方便之余也为SQL注入敞开了大门。显然如果这条SQL语句被执行的话,那么news表里的记录就都没有了。

 那么如何预防呢?很简单,因为ColID字段的类型是int的,那么我们只需要验证一下传递过来的id是不是整数就可以了。是整数就不存在注入;如果不是那么就有可能存在注入。即使不存在注入,把一个不是整数的id拼接进去也会造成执行错误。
  所以说不管是不是为了预防SQL注入,也都应该验证id是不是整数。  

  验证方法嘛,可以用TryParse,可以用正则,也可以自己写函数验证。但是不建议用try异常的方式,因为这个有效率问题。

  这里还有一个特殊情况,就是对于批量删除这类的会传递过来多个数字,比如“1,2,3,10”,这个也需要验证一下,万一有人利用这个漏洞呢。至于验证方法也很简单,自己写个函数就ok了。

2、日期时间

  这个和数字的情况是一样的,验证是不是日期时间即可。

3、字符串

最麻烦的就是这个了

 

比如我们先要按照新闻标题来进行查询,可能写的代码:

string key = txtTitle.Text;
string sql = "select * from news where title like '%"+ key + "%'";
这个又是如何注入的呢?我想先问大家一个问题:如果key的值永远都不会包含单引号,那么会不会被注入进来?

  那么用了单引号又是如何注入的呢?假设key=" ' delete from news --" ,那么sql的值就是“ select * from news where title like '%' delete from news -- ' ”。


  先用一个单引号和前面的单引号组成一对封闭的单引号,这一对单引号内部('%')就作为字符串处理,而外面的就被作为SQL语句处理,而第二个单引号被 “--”给注释掉了,这样就保证了整个sql语句的正确性。

  这是注入的一种方法。

  那么如何来防止呢?想想刚才的问题,如果没有单引号是不是就天下太平了呢?对于这种情况(前面的“数字”的情况不算),到目前为止我是没发现不用单引号,还能够注入进来的方法。也许是我孤陋寡闻吧,不知道各位高手是否知道对于这种情况,不用单引号还能注入进来的方法。

  既然找到了罪魁祸首,那么就好办了,把单引号干掉就ok了。key = key.Replace("'", "''");这时候sql的值就是” select * from news where title like '%'' delete from news --'”。
  对于SQL 来说在一对单引号内部的两个单引号表示一个字符串形式的单引号。这样我们就把罪魁祸首改造成了字符串了。在一对单引号内的“--”也是普通的字符串而不代表注释。

      微软推荐存储过程+参数的写法:

      可以写成这样: SELECT * FROM news WHERE title LIKE '%'+REPLACE(@title,'''','''''')+'%'

      并不是说只要使用参数SQLParameter就能避免sql注入了,首先可以利用参数的类型、长度等属性判断参数是否合法,通过这个检测就能过滤掉一些不合法的内容,然后再存储过程中sql语句拼接的时候,做一些处理,比如把一个单引号replace成两个单引号等。

 

  罪魁祸首是单引号,想不明白为什么有许多人都去过滤 “delete、update”这一类的关键字,他们都是安善良民呀,他们是很冤枉的。当然了,如果前提是程序都已经写好了,不能修改内部代码,那就另当别论了。至于“--”顶多算是帮凶,如果您不放心的话,把他处理了也行。

  总结:数字、日期时间的,验证类型字符串的,处理好单引号。
  另外为了安全起见,不要用sa连接数据库xp_cmdshell这一类的有危险的扩展存储过程也应该处理一下(比如删除)。

来源地址:

http://msdn.microsoft.com/zh-cn/library/ms161953(v=SQL.105).aspx

http://www.cnblogs.com/jyk/archive/2009/11/26/1610987.html

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值