位置:海鸟网 > IT > ASP.NET >

ASP.NET安全问题--创建安全的Web应用程序

  把一个问题说清楚,是要有前提的,也要大家有一些通过的词汇,就像大家谈OO,就知道谈的面向对象,以及面向对象的一些特征;懂设计模式的,一听到"观察者",就立马知道什么意思。

  一.下面看看安全的一些概念:

  首先,我们来看看什么是安全性?

  我们常常提起“实现安全性”“创建安全的系统”。所以安全性一般是定义很多,如:安全性就是保证系统可以完全按照我们想要的方式运行;安全性就是防止以我们不希望的方式运行系统...定义很多,但是不知道大家有没有发现,我们理解的安全的定义很狭窄的。怎么说?我们一般认为安全就是这样的:采取一定的措施(主要是编程代码的措施)处理程序运行时的意外,或者防止意外发生。但是安全的问题不仅仅只是代码的问题,所以在安全编程方面,我们要考虑的更多。

  什么是安全

  我们不能保证一个系统绝对的安全,不可能做到100%的安全。安全的定义的受到很多的限制,首先我们来看看一个例子。

  我们都用过银行的ATM机,如果有人捡到了我们的卡想要盗取我们的钱,那么他只有猜我们的密码。如果密码的长度只有一位数,那么捡卡人第一次猜对的概率就是1/10,他只要十次就可以盗取我们的钱(假设可以不限次数的猜),那么系统的安全行很差;如果密码是2位,那么密码就有100中可能,那么捡卡人第一次才对的几率就是1/100,第二次就是1/99,第三次1/98...系统的安全行也很差.

  如果把密码的尝试限制在3次,如果密码为2位数,那么密码被猜出的几率就大大的减小了:

  第一次猜中的几率就是1/100

  第二次猜中(第一次没有中)的几率就是(99/100) * (1/99)=0.01

  第三次猜中(前两次不中)的几率就是(99/100)*(98/99)*(1/98)=0.01

  三次之内猜中的几率就是:0.01+1.01+0.01=0.03

  所以,当我们限制了尝试的次数的时候,系统就比之前安全了一些,但是系统还并不是很安全,只能说比之前稍微的好了点,但是风险依然很大。

  为了使得系统更加的安全,就要减小系统的密码被猜出的可能行,我们可以从两个方面着手:

  1.使得密码尝试的次数减小,如用户只能输入一次密码;

  2.加大密码的位数,如6位。这样密码被猜出的几率就更加的小了,风险也小了很多,系统的安全行就又提高了。所以,我们常说安全不安全的,都只是一个相对的概念。说了这么多,就是要说一点:不要把安全看死了,安全不安全要看我们的环境。

  在谈后面的话题之前,让我们来共享一些术语:

  脆弱性是系统的一个特征,它可能会使得应用系统不安全按照我们预想的方式运行。一般表示系统不好的特征。

  威胁就是指利用错人性破环系统安全的可能行。

  利用就是利用脆弱行的方法。

  总结一句话就是:脆弱行导致了威胁,利用则实现了威胁,简言之,攻击。

  二、Web应用中的安全问题

  首先我们就看看对Web的攻击。攻击有很多种的,其中一部分可以使用ASP.NET代码进行防范的,但是其他的攻击方式还是可以产生破坏的,如直接攻击服务器。下面就来看典型的例子。

  我们之前说过,攻击就是利用系统的脆弱性以实现一定的威胁。攻击的结果也很多,如:

  未经授权的访问--用户获取了更多的权限,从而可以将应用程序用于其他的途径,如果获取了网站的管理员的密码,散布政治言论。

  代码执行--在目标系统上运行恶意代码,而且还会导致其他的威胁,如木马。

  拒绝服务--合法用户被禁止访问应用程序

  信息失窃--机密的信息被盗取

  破坏信息--信息遭到修改。如,站点被涂改,发布攻击性的消息和政治言论。

  下面我们就来看看常见的一些脆弱性,以及对它们的利用,以及引起的威胁。

  缓冲区溢出

  这个问题由来已久,而且到现在为止,也是Web应用种最常被利用的脆弱性。

  当应用程序的外部输入没有经过检查就被插入内存的时候,就会存在缓冲区溢出的脆弱性。如果插入的长度超过了内存中为此分配的空间的长度,输入就溢出,可能将占据内存中的其他的地方,甚至运行恶意的代码。

  对缓冲区溢出的主要利用就是把附加的数据写到内存中缓冲区的其他地方,这样就常常导致程序的崩溃,因为内存破坏了,这也是拒绝服务器的攻击方式,如果附加的数据设计的很巧妙的话,附加的数据还可以重写函数的返回地址,那么程序就按照攻击者的意愿执行,病毒,木马就是这样。

  当然,在c++中,这个问题很常见,因为C++可以直接操作内存地址,进行很底层的操作。但是在.NET中是否也有这个问题?

  因为.net是基于托管代码的,也就是说.net的代码不是直接操作内存,而是在中间隔了一层CLR。托管代码的执行要靠CLR来为止作为边界检查,所以CLR中的任何脆弱性都将转变为应用程序的脆弱性。如果有高手知道了CLR的问题,那么,托管代码也出问题。

  脚本注入和跨站脚本攻击

  任何时候我们都要有这个心理:用户都是恶意的。所以我们不能信任用户的任何输入,在用户输入的时候一定要检验。假如没有正确的处理好用户的输入,就可能在程序中引入脚本注入的脆弱性。该脆弱性允许用户将自己额脚本注入到数据中,如在用户留言中,用户插入" ",那么我们的留言的页面就中是弹出提示。

  跨站脚本的攻击一般表现为一个在URL参数中带有客户端的脚本。这些脚本用来盗取用户的cookie信息等,

  我们这里只是简单的说下,后面的一些文章还会具体的谈,以及解决方案。

  SQL注入

  相信这个问题,大家或多或少都知道一些,主要是恶意的用户在我们的程序的数据库中执行精心设计的SQL语句。而且威胁很大,设置可以获取服务器的管理员的权限。

  分布式拒绝服务

  也称为DDOS(Disrtibute Denial Of Service)。DDOS攻击主要就是用大量的计算机攻击一个系统。很多的计算机联合起来就可以发送很多的虚假的请求,以至于被攻击的系统超负荷,而不能向其他的用户提供服务。

  蓄意工具者为了发动DDOS,就必须获取足够多的机器。恶意的用户设计在别人的电脑上注入木马和病毒,获取机器的控制权,"借"别人的电脑发送攻击。被控制的电脑就是所谓的"僵尸"。

  DDOS攻击一般来攻击服务器,而且攻击的方式也是防不胜防,很多的防护软件和防火墙不能区分正确的请求和虚假的请求。

  人的问题

  有时候,被利用的脆弱性不是技术上的脆弱性,而是人的脆弱性。如果用户没有安全的意识,就容易受骗,而为攻击者打开系统的。方式很多,如用Email欺骗用户,诱使用户执行一些程序,还有就是蠕虫...

  蛮力攻击

  如果不采取一定的措施防止用户无休止的尝试连接应用程序,那么我们就容易受到不计其数的猜测密码口令的攻击,即蛮力攻击。

  攻击的方式主要就是设计一个程序,用它向目标应用发送很多的请求以测试不同的密码口令。

  有一点要注意:考虑安全问题的时候,我们常常把程序比作为一个城堡,在城堡的周围建造城墙并且严格盘查各个通道。保护Web程序与此类似,但是,如果这样,那么我们对于已经进入城堡的用户就无计可施了。