新闻中心

EEPW首页>模拟技术>设计应用> CGI安全问题专题

CGI安全问题专题

作者: 时间:2012-05-17 来源:网络 收藏
按钮未被选择,另一个就一定被选择了。下面的Perl 代码 就犯了这样的错误: if ($form _ Data{radio _ choice} eq button _ one){ # Button One has been clicked } else { # Button Two has been clicked } 这段 代码 假定因为表单仅提供了两个选项,而第一项未被选中,那么第二项就肯定被选中了。这不一定是真的。尽管前面的例子没有什么害处,但在某些情况下这样的假设可能很危险。脚本应该能预期这种情形而相应地进行处理。例如,如果出现一些非预期的或不可能的情形,可以打印一个错误,如下所述: If ($form _ Data{radio _ choice} eq button _ one) { #Button One seleted } elsif ($form _ Data{radio _ choice} eq button _ two) { #Button Two Selected } else { #Error } 通过加入第二个if语句——显式检查radio _ choice实际上是button _ two——这样脚本更安全了;它不再做假设了。 当然,错误不一定是期望脚本在这些情形下生成的。有些脚本过于小心,验证每个字段,即使是最轻微的非预期数据都生成错误信息,这样往往很扫用户的兴。让脚本识别非预期数据然后扔掉它,并且自动选择一个缺省值也可以。 另一方面,脚本还可帮助用户纠正错误而不是简单地发一条错误消息或设置一个缺省值。如果表单要求用户输入机密文字,脚本应能在进行比较之前自动跳过输入中的空白字符。下面即是一个完成此功能的Perl程序片段。 $user _ input =~ s/\\s//; #Remove white space by replacing it with an empty string if ($user _ input eq $secret _ Word) { #Match! } 最后,可以更进一,让脚本能处理尽可能多的不同的输入表单。尽管不可能预期到可能发送给CGI程序的所有内容,但对某个特定方面一般经常有几种常用的方式,因而可以逐个检查。 例如,仅仅因为所写的表单使用POST方法向CGI脚本提交数据,并不意味着数据必须按那种方法进来。应该检查REQUEET _ METHOD环境变量来确定是使用了GET还是POST方法并相应地读取数据,而不是假定数据都是来自预期的标准输入(stdin)。一个真正编写成功的CGI脚本能接收无论使用什么方法提交的数据并在处理过程中很安全。以下程序清单即是用Perl编写的一个例子。 程序清单 CGI _ READ.PL 一个充满活力的读取格式输入的程序 #Takes the maximum length allowed as a parameter #Returns 1 and the raw form data,or 0 and the error text sub cgi _ Read { local($input _ Max)=1024 unless $input _ Max=$ _ [0]; local($input _ Method)=$ENV{\REOUEST _ METHOO\); #Check for each possible REQUEST _ METHODS if ($input _ Method eq GET) { #GET local($input _ Size)=length($ENV{\QUERY _ STRING\}); #Check the size of the input if($input _ Size>$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 echoHTML>HEADER>TITLE>File/TITLE>HEADER>BODY> echoHere is the file you requested:PRE>\n cat $PATH _ INFO echo /PRE>/BODY>HIML> 尽管在用户只单击预定义的链接(即 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路径。
上一页 1 2 下一页

关键词:CGI安全问题

评论


相关推荐

技术专区

关闭