如何彻底防止SQL注入?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何彻底防止SQL注入?相关的知识,希望对你有一定的参考价值。
谢谢
1、对,限制用户输入肯定有效2、应该也可以做到,但正则不是一种高效的方法,用htmlEncode的方法可以有效防止空格等被DBMS解释,但注意别把编码、解码搞反了;存储过程是DBMS执行的一段程序,把数据操纵交给存储过程执行,而不是提交SQL语句,可以有效防止SQL注入。
3、地址栏的Sql攻击,下面我引用了一段资料解释,他关于机制说的较清楚,关于解决,只是从客户端考虑的,实际上用存储过程等都可以防范。
资料:
首先,入侵者会对一个网站确定可不可以进行注入,假设一篇文章的地址为:http://www.naohou.cn/show.asp?id=325一般会以提交两个地址来测试,如:
http://www.naohou.cn/show.asp?id=325 and 1=1
http://www.naohou.cn/show.asp?id=325 and 1=2
第一个地址后面加了 and 1=1,构成的SQL语句也就变为了:Select * from 表单名 where id=1 and 1=1这句话要成立就必须and前后语句都成立。那么前面的文章地址是可以访问的,后面的1=1也是客观成立的,那么第一个地址就可以正常显示;相反1=2是显然不成立的,关键就看这步了,如果提交and 1=2页面还是正常显示说明他并没有将and 1=2写入SQL语句,此站也就不存在注入漏洞;但如果提交and 1=2之后返回了错误页面则说明此站点将后面的语句带入了SQL语句并执行了,也就说明他可以进行SQL注入。(注:如果地址后面跟的是news.asp?id='1'就得变为news.asp?id=1' and '1'='1来补全引号了)
那么,知道可以注入后入侵者可以做什么呢?
这里就简单的说一下,比如提交这样的地址:
http://www.naohou.cn/show.asp?id=325 and exists (select * from 表名 where 列名=数据)
根据返回的正确或错误页面来判断猜的表名和列名是否正确,具体实现时是先猜表名再猜列名。当猜出表名和列名之后还可以用ASC和MID函数来猜出各列的数据。MID函数的格式为:mid(变量名,第几个字符开始读取,读取几个字符),比如:mid(pwd,1,2)就可以从变量pwd中的第一位开始读取两位的字符。ASC函数的格式为:ASC("字符串"),如:asc("a")就可以读出字母a的ASCII码了。那么实际应用的时候就可以写为:asc(mid(pwd,1,1))这样读取的就是pwd列的第一个字符的ASCII码,提交: asc(mid(pwd,1,1))>97以返回的页面是否为正确页面来判断pwd列的第一个字符的ASCII码是否大于97(a的ASCII码),如果正确就再试是否小于122(z的ASCII码)……这样慢慢缩小字符的ASCII码的范围,猜到真实的ASCII码也只是时间的问题。一位一位的猜就可以得到数据库中的用户名和密码了。还有一种ASP验证缺陷——就是用户名和密码都输'or '1'='1,构造SQL语句Select * form 表单名 where username='' or '1'='1' and pwd='' or '1'='1'就可以达到绕过密码验证的目的。
说了那么多,其实防范的方法很简单,我们把特殊字符(如and、or、'、")都禁止提交就可以防止注入了。ASP传输数据分为get和post两种, get是通过将数据添加到URL后提交的方式,post则是利用邮寄信息数据字段将数据传送到服务器。
参考资料:http://www.naohou.cn/
参考技术A SQL注入就像物理的误差,是不可以彻底防止的,只可能做到最佳状态。有彻底的办法还怕SQL注入? 参考技术B 这个世界有彻底的事情么,想一劳永易?那是不可能的楼上两条很中肯
如果再把数据库权限设置的更细点就好了,比如读写,对系统表,系统关键存储过程访问等 参考技术C 病从口入,SQL注入也是根据使用者输入特殊字符而导致的。而限制用户的输入并不是一个很好的办法,最好的办法就是在格式化用户输入的字符,最终形成一个理想的SQL查询语句,我用的是ASP写了一个函数,用来转换用户提交的数据,杜绝用户SQL注入行为。
如果使用的是其他语言可以仿照改写一下。
Function CData(ByVal strWord, ByVal intType)
On Error Resume Next
Select Case intType
Case 0
CData = 0
If IsNumeric(strWord) Then If strWord Then CData = 1
Case 1
CData = 0
If IsNumeric(strWord) Then CData = CInt(CByte(strWord))
Case 2
CData = 0
If IsNumeric(strWord) Then CData = CInt(strWord)
Case 3
CData = 0
If IsNumeric(strWord) Then CData = CLng(strWord)
Case 4
CData = 0
If IsNumeric(strWord) Then CData = CCur(strWord)
Case 5
CData = Now()
If IsDate(strWord) Then CData = strWord
Case 6
CData = ""
If strWord > "" Then CData = Replace(Replace(strWord, CHR(0), ""), "'", "''")
Case 7
If strWord > "" Then
strWord = Replace(strWord, CHR(0), "")
strWord = Replace(strWord, "'", "''")
strWord = Replace(strWord, "[", "[[]")
strWord = Replace(strWord, "%", "[%]")
CData = Replace(strWord, "_", "[_]")
Else
CData = ""
End If
Case Else
CData = ""
If strWord > "" Then CData = CStr(strWord)
End Select
On Error Goto 0
End Function
参考资料:http://hi.baidu.com/%C1%F7%CF%E3%D3%F0/blog/item/e223c3ca1e43ef47f31fe73f.html
参考技术D 不使用数据库全部静态页面
防止sql注入的方法都有哪些
参考技术A 根据本人实际经验总结,非照搬教科书。一种就是在服务器上安装安全软件,这种安全软件能够自动识别注入攻击,并做出响应策略。再就是你的所有request都要进行程序过滤,把包含sql的一些特殊字符都过滤掉。第三就是数据库sql语句可以采用一些预编译的框架,如Mybatis,也能防止sql注入。以上是关于如何彻底防止SQL注入?的主要内容,如果未能解决你的问题,请参考以下文章