一个极其简单的防止SQL注入的办法(只针对部分有效)转自csdn论坛
2010-10-24 20:10
393 查看
首先,先声明一下,这个办法是我WoW时候忽然想出来的,绝不会完美。
其次,说明一下我的方法的大致思想:判断最后要提交到数据库的SQL,通过禁止某些可能具有危害性的SQL的执行而达到防止SQL注入的目的。判断每个QueryString是很麻烦的(至少像我这种懒人觉得麻烦),而只判断最后那句SQL要简单很多。并且可以做个通用的函数,简单地调用一下即可。
先研究一下可能的SQL注入的特点。如果什么安全措施也不做,那么最后提交到数据库的SQL很可能是这样:
http://www.abcdefg.com/type.asp?id=6;update admin set password='helloworld' where username='admin'--
Select * from abc where id = 6 ;update admin set password ='helloworld' where username='admin'--
那么应对措施如下:
1) 判断SQL中有没有注释符号
自己写的SQL还用得着注释?并且注释居然不是写在代码里而是写在SQL里?先汗一下。在SQL中出现注释符号的直接pass,这必然不是什么好东西。
if ( sql.Contain("--") ) throw new Exception("SQL injection!");
2) 判断SQL是不是一句话
上例中因为有; 的存在而使本来好好的一个查询变成了两句话,而第二句话基本上就不会是什么好东西了。我可以通过判断这个SQL中有没有;的存在来判断这句SQL是不是一句话。
if ( sql.Contain(";") ) throw new Exception("SQL Injection!");
3) 很有可能这些危险的符号是用十六进制存放的,那么就需要翻译一下。
所谓“智者 当借力而行”,我们可以用现成的库函数来实现这个翻译过程
sql = Server.UrlDecode( sql ); // 把这句话放在 1 和 2 的前面
4) 说不定在一些奇怪的查询中,;是作为关键字的一部分而存在的。但请注意,有这种需求的一般都是要接收一个字符串作为参数,那么这个正常的;应该是被包括在一对引号当中的。为了剔除这种情况,我们可以先用正则把所有的'!@#$'替换掉,再进行下一步的检测。
sql = Regex.Replace(sql, @"/'.*/'", ""); // 把这句话放在 3 的后面
如此几步下来,类似例中给出的SQL注入就会被检测出来。
完整代码;
public class SqlDetector
{
public static void Detect(string sql)
{
sql = Regex.Replace(sql, @"/'.*/'", "");
sql = Server.UrlDecode( sql );
if ( sql.Contain("--") ) throw new Exception("SQL injection!");
if ( sql.Contain(";") ) throw new Exception("SQL Injection!");
}
}
遗憾;
对于诸如 http://www.abcdefg.com/type.asp?id=(select password from admin)-- 这样的SQL注入还没有办法,不过既然没有办法再继续 update,得到密码就得到了吧。您的密码居然还是用明文存放的?!
全文完。
欢迎讨论!欢迎拍砖!
其次,说明一下我的方法的大致思想:判断最后要提交到数据库的SQL,通过禁止某些可能具有危害性的SQL的执行而达到防止SQL注入的目的。判断每个QueryString是很麻烦的(至少像我这种懒人觉得麻烦),而只判断最后那句SQL要简单很多。并且可以做个通用的函数,简单地调用一下即可。
先研究一下可能的SQL注入的特点。如果什么安全措施也不做,那么最后提交到数据库的SQL很可能是这样:
http://www.abcdefg.com/type.asp?id=6;update admin set password='helloworld' where username='admin'--
Select * from abc where id = 6 ;update admin set password ='helloworld' where username='admin'--
那么应对措施如下:
1) 判断SQL中有没有注释符号
自己写的SQL还用得着注释?并且注释居然不是写在代码里而是写在SQL里?先汗一下。在SQL中出现注释符号的直接pass,这必然不是什么好东西。
if ( sql.Contain("--") ) throw new Exception("SQL injection!");
2) 判断SQL是不是一句话
上例中因为有; 的存在而使本来好好的一个查询变成了两句话,而第二句话基本上就不会是什么好东西了。我可以通过判断这个SQL中有没有;的存在来判断这句SQL是不是一句话。
if ( sql.Contain(";") ) throw new Exception("SQL Injection!");
3) 很有可能这些危险的符号是用十六进制存放的,那么就需要翻译一下。
所谓“智者 当借力而行”,我们可以用现成的库函数来实现这个翻译过程
sql = Server.UrlDecode( sql ); // 把这句话放在 1 和 2 的前面
4) 说不定在一些奇怪的查询中,;是作为关键字的一部分而存在的。但请注意,有这种需求的一般都是要接收一个字符串作为参数,那么这个正常的;应该是被包括在一对引号当中的。为了剔除这种情况,我们可以先用正则把所有的'!@#$'替换掉,再进行下一步的检测。
sql = Regex.Replace(sql, @"/'.*/'", ""); // 把这句话放在 3 的后面
如此几步下来,类似例中给出的SQL注入就会被检测出来。
完整代码;
public class SqlDetector
{
public static void Detect(string sql)
{
sql = Regex.Replace(sql, @"/'.*/'", "");
sql = Server.UrlDecode( sql );
if ( sql.Contain("--") ) throw new Exception("SQL injection!");
if ( sql.Contain(";") ) throw new Exception("SQL Injection!");
}
}
遗憾;
对于诸如 http://www.abcdefg.com/type.asp?id=(select password from admin)-- 这样的SQL注入还没有办法,不过既然没有办法再继续 update,得到密码就得到了吧。您的密码居然还是用明文存放的?!
全文完。
欢迎讨论!欢迎拍砖!
相关文章推荐
- 解决UIScrollView截获touch事件的一个极其简单有效的办法
- PHP + Mysql 登录功能防止SQL注入的一个办法
- 一个简单无脑的防止内存重启后导致Fragment重叠的解决办法
- PHP + Mysql 登录功能防止SQL注入的一个办法
- python 替换字符串中指定位置字符——一个简单有效的方法
- node.js做的一个简单爬虫,适合菜鸟级新手,针对无防爬措施的网站
- "创建控件时出错/lm/w3svc/... 不是一个有效的iis应用程序" 的解决办法
- Apache下有效防止盗链仿下载的解决办法
- [转]创建控件时出错/lm/w3svc/... 不是一个有效的iis应用程序" 的解决办法
- 防止sql注入的简单方法
- 笨办法学 Python · 续 第二部分:简单的黑魔法
- 一个极其简单的函数。。练练手
- jsforum研究。一个比较简单的论坛。
- 开发一个安全的小网站(一)防止sql注入
- 『Visual C++ MFC 简明教程』----第二部分:一个简单的MFC程序
- Lex和Yacc从入门到精通(3)--一个极其简单的lex和yacc程序
- 防止点击同一按钮多次,弹出同一窗体多个的j简单办法
- QuickPlay2.0安装到XP环境下遇到的一部分问题的原因及部分有效的处理办法
- PHP简单代码防止SQL注入
- 项目经验之:针对昨日FDO连接SDF文件报错,国个GIS论坛给出了一个思路.帮助我过关.