您好,欢迎来电子发烧友网! ,新用户?[免费注册]

您的位置:电子发烧友网>电子百科>语音视频>安防监控>

CGI安全问题专题

2010年01月14日 09:54 www.elecfans.com 作者:佚名 用户评论(0

CGI安全问题专题

在 计算机 领域——尤其在Internet上——尽管大部分Web 服务 器所编的程序都尽可能保护自己的内容不受侵害,但只要CGI脚本中有一点安全方面的失误--口令文件、私有数据、以及任何东西,就能使 入侵 者能访问 计算机 。遵循一些简单的规则并保持警惕能使自己的CGI脚本免受侵害,从而可以保护自己的权益。 1. 脚本和程序 在开始决定采用何种语言编写CGI脚本时应考虑几个因素,其中之一应是安全性。Shell 脚本,Perl程序和C可执行程序是CGI脚本最常采用的形式,从安全性角度来说每种都备有优缺。尽管没有哪一种是最好的--基于其他方面的考虑,如速度和可重用性--每种都有实用的领域。 Shell脚本一般用于小的、快速的甚至可以用完就不要的CGI程序,因此,编写它们时常常不考虑安全性。这种疏忽可以导致一些缺陷,使得仅对系统具有一般 知识 的人也能进入系统任意走动。 尽管Shell CGI 程序最容易写,甚至只需拼凑一下即可,但控制它们却很困难,因为它们一般是通过执行外部的其他程序来完成工作的。这就导致一些可能的隐患,CGI 程序会继承任何它使用的程序的安全问题。 例如,常用UNIX实用程序 awk对于它能处理的数据的数量有一些相当严格限制。如果在CGI脚本中使用awk,那么该程序也就有了同样的限制。Perl比Shell脚本更进一步。Perl用于CGI 编程 有很多优点,并且相当安全。但Perl能给CGI 作者提供足够的灵活性从而导致对安全性的错误感觉。例如,Perl是解释型的。这意味着它实际在调用时是先编译,然后每次执行一步。这就很容易使得不正确的用户数据被包括进来作为 代码 的一部分,从而错误地进行解释,形成程序中止原因。 最后谈谈C。C迅速成为标准应用开发语言,几乎所有的UNIX和windows NT系统都是用它开发的。从安全性的角度来看C 似乎是很不错,但由于它的流行性,它的好几种安全性问题已广为人知,而这些问题也能很容易地被人利用。 例如,C 对串处理非常差。它不做任何自动的定位或清理而让 编程 者自己处理所有事情。在处理串时,大部分C 程序员都是简单地建立一个预定义的空间并希望它足够大以便处理用户输入的任何内容。 当然,Shell脚本、Perl和C 不是仅有的编写CGI脚本语言。实际上,任何可以按预定义的方式与Web 服务 器进行交互的 计算机 语言都可以用于编写CGI程序。在UNIX和Windows NT 服务 器上,数据是通过环境变量和标准输入(stdin) 传给脚本的,所以任何能从这两种数据源读取并写入标准输出(sidout)的语言都能用于创建CGI:awk、FORTRAN、C++、Basic和COBOL,等。windows的程序员可以使用流行的Visual Basic,这意味着有经验的VB程序员不必去学一门新语言。Macintosh使用AppleEvents、和AppleScript与CGI程序进行通信,所以任何可以读写这两者的语言都可使用。 不过,Shell脚本(不管使用那种Shell)、Perl和C仍是最流行为的编写CGI脚本的语言。这并不是说必须使用它们了只是说大部程序的库——即大部分经过测试的安全的库——都是用这三种语言编写的。如果自己来选择CGI 编程 语言,最好是借鉴前人的经验。 2. 谁也不信 几乎所有的CGI 安全问题都来自与用户的交互。接收来自外部数据源的输入之后一个简单的、可预见的CGI程序突然向多方向伸展,每个方面都可能有最小的缝隙使得“黑客”可以溜进来。正是与用户的这种交互——通过表单或文件路径——才给予了CGI 脚本这种能力,但同时也使得它们成了运行在Web 服务 器上的最潜在的危险部分。 编写安全的CGI 脚本很大程度上是创造性和妄想的结合。编写者必须有足够的创造性才能想到用户使用的,不管是无意地还是别的所有的可能隐含导致问题的发送数据的方式。而且必须有点妄想,因为有可能不知道什么时候、什么地方、他们将会一一加以试验。 2.1 两种导致问题的方式 当用户登录进入Web 站点并开始进行交互访问时,他们能以两种方式惹麻烦。一种是不遵守规则,歪曲或违反页面中建立的每个限制或约束;另一种方式是按要求去做。 大部分CGI 脚本是作为HTML表单的后台运行的,负责处理由用户输入的信息并提供某种定制的输出。因为在这种情况下,大部分CGI 脚本编写时都等待某种特殊格式的数据。它们期望用户的输入能匹配收集并发送信息的表单。不过事情并不总是这样。用户可以有许多种办法绕过这些预定义的格式而给脚本发送一些看起来是随机的数据。CGI 程序必须对此有所准备。 其次,用户可以给CGI 脚本发送所期望的数据类型,按预期的形式在表单中填入每个字段。这种类型的提交可以是想像中的来自某个与站点交互的无意的用户,也可能来自某个恶意的“黑客”,凭借他有关操作系统和Web 服务 器 软件 的 知识 并利用常见的 编程 错误。这些 入侵 ,表面上一切都正常,却是最危险的、最难检测出来。Web 站点安全性依赖干这种 入侵 的防止。 2.2 不要相信表单数据 在CGI 编程 中最常见的安全失误就是相信从表单传到脚本的数据,用户是未知的一大堆人,他们总能找到一些 编程 人员从来没想到过的发送数据的方法--而且是程序员认为几乎不可能的方法。 脚本必须对这些加以考虑。例如,下面这些情形都是可能的: 1)从一组单单选按钮中选择的结果可能不是表单中提供的选项之一。 2)来自某个文本字段的数据长度可能大于MAXLENGTH字段允许的长度。 3)字段本身的名字可能与表单中指定的不相符。 2.3 不合理数据的来源 因—些无意的或是有意的原因,导致自己的脚本接收到不知道如何去处理的数据,有可能导致非预期的——同时很危险的——行为。 下面的 代码 实现了一种表单并向某个搜索yahoo! 数据库 的CGI脚本送垃圾。该脚本设计得很好并且很安全,因为它忽略了不认识的输入。

Enter your name,first then last: $input _ Max) { return(0,input too big); } #Read the input from QUERY _ STRING return(1,$ENV{\\\QUERY _ TRING\\\}); } elsif ($input _ Method eq POST) { #POST local($input _ Size)=$ENV{\\\CONTENT _ LENGTH\\\}; local($input _ Data); #Check the size of the input if ($input _ Size>$input _ Max) { return(0,Input too big); } #Read the input from stdin unless (read(STDIN,$input _ Data,$input _ Size)) { return(0,Could not read STDIN); } return(1,$Input _ Data); } #Unrecognized METHOD return (0,METHOD not GET POST); } 总而言之,脚本应该不对接收的表单数据进行假设,应尽可能预计意料之外的情形并正确地处理不正确的或错误的输入数据。在使用数据之前应按尽可能多的方式测试它拒绝不合理的输入并打印一条错误消息如果某项出错或漏了应自动选择一个缺省值甚至可以试图对输入进行编码以成为程序的合理的输入。选择哪种方式依赖于自己想花费多少时间和精力,不过记住永远也不要盲目接收传给CGI脚来的所有信息。 2.5不要相信路径数据 用户能修改的另一类型数据是PATH _ INTO的 服务 器环境变量。该变量由CGI URL中紧跟在脚本文件名之后的任何路径信息填充的。例如,如果foobar.sh是一个CGl shell脚本,那么当foobar.sh运行时,URL http://www.server.com/cgi-bin/foobar.sh/extra/path/info 将导致/extra/path/info被放进PATH _ INFO环境变量中。 如果使用这个PATH _ INFO环境变量,就必须小心地完全验证它的内容。就像表单数据能以许多种方式被修改一样,PATH _ INFO也可以修改。盲目地根据PATH _ INFO的中指定的路径文件进行操作的CGI脚本可能会让恶意的用户对 服务 器造成伤害。 例如,如果某个CGI脚来设计用于简单地打印出PATH _ INFO中引用的文件,那么编辑该CGI URL的用户就可以读取机器上的几乎所有文件,如下所示: #!/bin/sh #Send the header echo Conext-type:text/html echo #Wrap the file in some HTML #!/bin/sh echo
File
echoHere is the file you requested:
\\n cat $PATH _ INFO echo 
尽管在用户只单击预定义的链接(即 http://www.server.com/cgi-bin/foobar.sh/public/faq.txt )时,该脚本正常工作,但是一个更有创造性的(或恶意的)用户可能会利用它接收 服务 器上的任何文件。如果他想进入 http://www.server.com/cgi-bin/foobar.sh/etc/passwd ,前面的脚本会很高兴地返回机器的口令文件——这可是不希望发生的事。 另一种安全得多的方式是在可能时使用PATH _ TRANSLATED环境变量。不是所有的 服务 器都支持该变量,所以脚本不能依赖于它。不过如果有的话,它能提供完全修饰的路径名,而不是像PATH _ INFO提供的相对URL。 不过在某种情形下,如果在CGI脚本中使用PATH _ TRANSLATED的话,则可以访问通过浏览器不能访问到的文件。应该知道这点及它的应用。 在大部分UNIX 服务 器上,htaccess文件可以位于文档树的每个子目录,负责控制谁能够访问该目录中的特殊文件。例如它可以用于限制一组Web页面只给公司雇员看。 虽然 服务 器知道如何解释.htaccess,从而知道如何限制谁能还是不能看这些页面,CGI脚本却不知道。使用PATH _ TRANSLATED访问文件树中任意文件的程序有可能碰巧覆盖了 服务 器提供的保护。 无论使用PATH _ INFO还是PATH _ TRANSLATED,另一个重要的步骤是验证路径以确保它或者是一个真正的相对路径或者是脚本认可的几个准确的、预知的路径之一。对于预定的路径,脚本将简单地将提供的数据与认可可以使用的文件的内部清单进行比较,这就是说在增加文件或修改路径时必须重新编译脚本,但安全性却有了保障。只允计用户选择几个预定义的文件而不允许用户指定实际的路径和文件名。 下面是处理访问者提供的路径时应遵循的一些规则。 1)相对路径不以斜线开头。斜线意味着相对于根或绝对路径。如果有的话,CGI脚本也是很少需要访问Web根之外的数据。这样它们使用的路径就是相对于Web根目录,而不是绝对路径。应拒绝任何以斜线开始的内容。 2)在路径中单个点(.)和两个点(..)的序列也有特殊含义。单点意味着对对于当前目录,而双点意味着相对于当前目录的父目录。聪明的黑客可以建立象../../../etc/passwd这样的串逆向三层,然后向下进入/etc/passwd文件。应拒绝任何包含双点序列的内容。 3)基于NT 服务 器使用驱动器字母的概念来引用磁盘卷。包含对驱动器的引用的路径都以一个字母加上一个冒号开头。应拒绝任何以冒号为第二个字符的内容。 4)基于NT的 服务 器还支持Univesal Naming Conventions(UNC)引用。一个UNC文件规格指定机器名和一个共享点,其余部分与指定机器上的指定的共享点有关。UNC文件规格总是以两个反斜线开头。应拒绝任何UNC路径。

非常好我支持^.^

(0) 0%

不好我反对

(0) 0%

相关阅读:

( 发表人:admin )

      发表评论

      用户评论
      评价:好评中评差评

      发表评论,获取积分! 请遵守相关规定!