如何彻底防止SQL注入?
发布网友
发布时间:2022-04-25 15:44
我来回答
共9个回答
热心网友
时间:2022-04-08 00:41
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/
热心网友
时间:2022-04-08 01:59
SQL注入就像物理的误差,是不可以彻底防止的,只可能做到最佳状态。有彻底的办法还怕SQL注入?
热心网友
时间:2022-04-08 03:33
这个世界有彻底的事情么,想一劳永易?那是不可能的
楼上两条很中肯
如果再把数据库权限设置的更细点就好了,比如读写,对系统表,系统关键存储过程访问等
热心网友
时间:2022-04-08 05:25
病从口入,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
热心网友
时间:2022-04-08 07:33
不使用数据库
全部静态页面
热心网友
时间:2022-04-08 09:57
比如设定输入长度,检查关键字等等
热心网友
时间:2022-04-08 12:39
1 用存储过程
2 转换为int类型
如 id = Convert.ToInt32(Request.QueryString["id"]);
热心网友
时间:2022-04-08 15:37
SQL注入并不是一个在SQL内不可解决的问题,这种攻击方式的存在也不能完全归咎于SQL这种语言,因为注入的问题而放弃SQL这种方式也是因噎废食。首先先说一个我在其他回答中也曾提到过的观点:没有(运行时)编译,就没有注入。
SQL注入产生的原因,和栈溢出、XSS等很多其他的攻击方法类似,就是未经检查或者未经充分检查的用户输入数据,意外变成了代码被执行。针对于SQL注入,则是用户提交的数据,被数据库系统编译而产生了开发者预期之外的动作。也就是,SQL注入是用户输入的数据,在拼接SQL语句的过程中,超越了数据本身,成为了SQL语句查询逻辑的一部分,然后这样被拼接出来的SQL语句被数据库执行,产生了开发者预期之外的动作。
所以从根本上防止上述类型攻击的手段,还是避免数据变成代码被执行,时刻分清代码和数据的界限。而具体到SQL注入来说,被执行的恶意代码是通过数据库的SQL解释引擎编译得到的,所以只要避免用户输入的数据被数据库系统编译就可以了。
现在的数据库系统都提供SQL语句的预编译(prepare)和查询参数绑定功能,在SQL语句中放置占位符'?',然后将带有占位符的SQL语句传给数据库编译,执行的时候才将用户输入的数据作为执行的参数传给用户。这样的操作不仅使得SQL语句在书写的时候不再需要拼接,看起来也更直接,而且用户输入的数据也没有机会被送到数据库的SQL解释器被编译执行,也不会越权变成代码。
至于为什么这种参数化的查询方式没有作为默认的使用方式,我想除了兼容老系统以外,直接使用SQL确实方便并且也有确定的使用场合。
热心网友
时间:2022-04-08 18:51
参数化sql语句