来自:lqx651 > 馆藏分类
配色: 字号:
让你的程序更安全,谈谈10年来的一些安全体会
2012-02-29 | 阅:  转:  |  分享 
  
写这个文章,告诉一些开始学习写程序的人,怎么让他的代码更安全。从我写ASP到现在,大约有1年了,我写ASP的时候,那时用WINNT4.0环境,安全性很不好,在地址后加几个特殊字符,就可以看到ASP的源代码了,后来,在多年写ASP的过程中,碰到无数的黑客试图黑我作的网站,花样百出,因此我一直特别注重程序的安全性。现在为止,很久没有写ASP了,改为用c#写ASP.NET,不可否认,ASP.NET由于结构的关系,确实容易比ASP做得更安全,但是,在ASP中几乎所有潜在的安全危险,在ASP.NET中几乎都存在,好处是ASP.NET源代码不开放,因此,黑客不太容易琢磨你这个系统的代码后,作很有针对性的攻击。实际上,我认为,不管ASP,ASP.NET,PHP,JSP,甚至是C/S结构的程序,都可能面临两个主要的共同的安全威胁:1.注入SQL。2.上传木马。而对网站程序,或是所有B/S结构的程序的开发者而言,他们要作的,主要就是防这两项,其它的都是小问题了,这两个搞定,网站一般就不那么容易被黑了。1.注入SQL,我们先看看什么是SQL注入,就是想办法提交一个特殊的字符串,改变你的SQL语句,让其变成其它的意思,达到黑客的目的,我举个非常简单例子,比如,我要验证一个用户的用户名和密码,如果找到了这个用户,就让他登录,很多入门的人,会写这么一个SQL语句:SELECTFROMUSERSWHEREUserName=''ADMIN''andPassWord=''123456''?这个语句看起来没问题,从用户输入的文本框中,得到用户名和密码,然后用他们来组装SQL语句,如果找到这个记录,说明用户名和密码正确,让他登录,如果找不到,说明错误,不让他登录,这看起来很完美,但实际上,这个语句完全没有安全性,如果用户在密码那里,输入一个''or1=1,这样一样,我们看这个语句成了什么呢?SELECTFROMUSERSWHEREUserName=''ADMIN''andPassWord=''''or1=1?好了,这样他就能以ADMINA的身份登录了,我们再想一下,如果这个黑客,他多花点心思,就可以写入一些修改数据库,罗列数据,破坏数据的语句,这就是SQL注入。那怎么注入SQL语句呢?方法很多,最简单的,比如我们看很多网站,都有这样的地址,比如:http://www.nmhlgl.com/bbs/index.asp?menuid=1352?这样的地址。这里我们要用menuid这个参数,往SQL语句中传值,于是这成了一个注入的入口,这是最简单的。还有一种,很多网页上,都要填写表单,比如作站内搜索,我们知道这个文本框提交之后,也会用来组装SQL语句,这也成了注入的切入点。第三种,用COOKIES,很多用站点,他会用一些COOKIES来保存一些用户数据,比如让用户不掉线,过了SESSION的有效期后,用COOKIES中的数据登录一次,用户看起来就不会掉线了。但这个COOKIES是可能被有的软件改写的,于是成了SQL注入的来源。如何防止SQL注入?从上面,我们看到,凡是SQL注入,黑客必然会想办法提交一些特殊的字符串给我们的程序,组装出一个异常的SQL字符串,那么,实际上要仿SQL注入,本质上,就是要对客户端提交的数据小心在意,我们可以用下面的办法让黑客的招数失效。第一,过滤,所以要用来组装SQL语句,并且这数据的来源是是从客户端的来字符串,我们都对它进行过滤,把一些危险可能用来注入SQL但实际上并不常用字符串过滤掉,比如单引号,大于号,小于号,等于号,空格之类,把这些过滤之后,黑客就没法组装出正确的SQL语句,程序执行到那里就会出错。它就不能得逞了。第二,严谨规范的语句,这主要是写Request时要小心。很多人,不管读COOKIES,GET提交的数据,POST提交的数据,统统用一个Request来解决,这个是很危险的。这是怎么回事呢?有一次,我发现我写的程序,被人注入了,因为每个语句去写过滤的代码太累了,所以我就在程序的前面,写了一个遍历所有GET,POST提交的数据的程序,只要发现这里面有非法字符,就过滤掉,按理说应该很安全呀,结果后来,我发现我的程序,所有获取数据时,都是写的Request[“A”],这样的代码,没有区别,结果黑客就自己假造了一个COOKIES,利用COOKIES比较优先,从而绕过了我的过滤,成功的注入SQL,从此之后,我就认真的成:Request.Form;Request.QueryString;Request.Cookies;第三,用存储过程,有时,我们会碰到一些不能过滤,但又要用来作查询条件的东西,这时怎么办呢?用存储过程,把这些本来要用来组装SQL语句的字符串,变成存储过程的参数,在存储过程中查询,这样,就避免了组装SQL语句,不给黑客机会。但也要注意,有一次,我看到一个程序员作的程序,他说他用了存储过程,还是被黑了,怎么回事呢?我看看,发现这人,好家伙,他把参数传进去,在存储过程中过程中组装成一个SQL字符串,再EXEC执行他,晕呀。我前面写过一些我的经验,有朋友说要源代码,其实,我觉得了解方法是最重要的,道理懂了,那几个代码,还不是很容易的事?你不懂道理,拿到代码又有何用?所以,我注重于介绍初学者一些方法,一些思路,而不是给一堆代码了事。



献花(0)
+1
(本文系lqx651首藏)