给认为SQL注入不仅仅只需要转换整数和过滤单引号,还需要考虑编码问题的人解惑

昨天看到一篇 预防SQL注入攻击之我见  ,发现好多人认为防止sql注入很麻烦,要考虑编码等等。

 

sql注入的本质上是程序员写的拼凑的SQL语句的某个部分需要一个字面值,而这个字面值却是由最终用户决定,最终用户可以构造一个错误的字面值来改变这条SQL语句的语义。

 

字面值有哪些呢?一般就是数字和字符串,日期在access里可以用#符号包含进来作为字面值,在sqlserver里似乎不能直接作为字面值。

预防SQL注入攻击之我见 里的数字处理其实不全面,全转为整数,如果是浮点数怎么办?

 

那么如何防止sql注入呢?让字面值不提前出现闭合符号,即单引号里不能出现单引号(替换一个为两个单引号,数据库本身转义),#里不能出现#,但是数值型的比较麻烦,没有符号将它包含起来,导致和命令的语法一致,那么只能将输入转换为原来的类型才处理了。日期型在sqlserver里,一般是通过CAST('2006-04-04 15:50:59.997' AS datetime) AS UsingCast等方法转换后处理的,所以既可以通过转换为日期来判断,也可以过滤单引号来处理注入。

如果愿意的话,把数值型也作为字符串处理,统一通过过滤单引号也是可行的,效率可能会有所下降, where Id='50',Id数据库类型是整型,也是会隐设转换的

 

特殊情况,比如 where id in (1,2,3) 如果括号里自行输入,那么输入select id from [表名],会将全部记录输出,不过这种情况也没有改变语义,但是如果输入 1);delete from [表名];select (1 这样就改变语义了,究其原因,还是由于字面值的界定符被别人闭合了,这种情况我们就要处理()括号符号了。

 

 

 

posted @ 2009-11-27 13:20  我想我是风  阅读(3301)  评论(31编辑  收藏  举报