CGI 安全问题警告 由于经常被恶意地使用,服务器端的include经常被禁止使用以保护站点免受侵害。现在假定这些都没问题。即使关闭了服务器端的include并且不介意用户能看到自己硬盘上的任何图片或者改变页面显示的外观,也仍然有问题--不仅是针对编程者的,而且针对其他用户。 CGI脚本的一个通常用途是留名册(guestbook):访问站点的顾客可能签个名,让别人知道他们已经在那儿了。一般情况下用户简单地输入他的名字,该名字会在访问者清单中出现。但是,如果将The last signee!<FORM><SELECT>作为用户名输入怎么办?<SELECT>标记将导致Web浏览器忽略位于<SELECT>和一个不存在的</SELECT>之间的所有内容,包括以后清单中加入的任何名字。即使有10个人签了名,仅有前3个会显示出来,因为第三个名字包含一个<FORM>和一个<SELECT>标记。因为第三个签名者在他的名字中使用了HTML标记,他后面的任何名字都不会显示出来。 对于用户输入HTML而不是普通的文本的情况有两种解决办法: 1)快速但比较粗糙的办法是不允许小于号(<)和大于号(>),因为所有HTML标记必须包含在这两个字符中,所以清除它们(或者如果碰到它们就返回一个错误)是一种防止HTML被提交并返回的简单的办法。下面一行Perl代码简单地清除了这两个字符:$user_Input=~s/<>//g; 2)更精细一点的办法是将这两个字符转换成它们的HTML换码--—种特殊的代码,用于表示每个字符而不使用该字符本身。下面的代码通过全部用<替换了小于符号,用>替换了大于符号,从而完成了转换: $user_Input=~s/</&1t;/g; 2.10 处理外部进程 最后,CGI脚本如何与带有外部过程的用户输入打交道是应该警惕的另一区域。因为执行一个位于自己的CGI脚本之外的程序意味着无法控制它做什么,必须尽最大努力在执行开始前验证发送给它的输入。 例如,shell脚本经常错误地将一个命令行程序和表单输入合在一起执行。如果用户输入符合要求,一切都挺正常,但是有可能会加入其它命令并非法执行。 下面即是一个产生了这种错误的脚本的例子: FINGER_OUTPUT='finger$USER_INPUT' 如果用户很礼貌地给finger输入了某人的e-mail地址,一切都会正常工作,但是如果他输入了一个e-mail地址,后面再跟一个分号和另一条命令,那么该命令也会被执行,如果用户输入了webmaster@www.server.com;rm-rf/,那麻烦可就大了。 即使没有什么隐藏的命令被加入用户数据,无意的输入错误也可能带来麻烦。例如,下面的代码行会产生一个意料之外的结果——列出目录中的所有文件——如果用户输入是一个星号的话。 echo "Your input:"$USER_INPUT 当通过shell发送用户数据时,就象前面的代码片段所做的那样,最好检查一下shell的meta-character(元字符)——这些可能会导致意外的行为。 这些字符包括分号(允许一行中有多条命令),星号和问号(完成文件匹配),感叹号(在csh下指运行的作业),单引号(执行一条包含其中的命令)等等。就像过滤文件名一样,维护一个允许的字符清单一般要比试图找出每个不允许的字符容易一些。下面的Perl代码片段验证一个e-mail地址: if ($email_Address ~= /[^a-zA-z0-9_-+@.]) { 如果决定在输入中允许shell元字符,也有办法让它们安全一些。尽管可以简单地给未验证的用户输入加上引号以免shell按特殊字符进行操作,但这实际上不起什么作用。请看下的语句: echo"Finger information:<HR><PRE>" 尽管$USER_INPUT上的引号可以使shell不再解释一个分号,从而不允许黑客简单地插进来一条命令,但该脚本仍有许多安全方面的漏洞。例如,输入可能是'rm-rf/',其中单引号可以导致甚至在finger不知道的情况下执行黑客的命令。 一种处理特殊字符的较好的办法是对它们进行换码,这样脚本只是取它们的值而不解释它们。通过对用户输入进行换码,所有的shell元字符都被忽略并作为增加的数据传给程序。下面的Perl代码即对非字母数字字符完成这种处理。 $user_Input=~s/([^w])/\1/g; 现在,如果用户输入加在某条命令之后,每个字符——即便是特殊字符——都会由shell传送给finger。 不过请记住,验证用户输入——不相信发送给自己的任何信息——会使自己的代码更易读并且执行起来更安全。最好不是在已经执行了命令之后再去对付黑客,而应在门口就对数据进行一次性的检查。 -------------------------------------------- 处理内部函数 对于解释型语言,例如Shell和Perl,如果用户输入的数据不正确的话,有可能导致程序生成本来没有的错误。如果用户数据被解释为一部分执行代码,用户输入的任何内容都必须符合语言的规则,否则就会出错。 例如,下面的Perl代码片段也许会正常工作也许会产生错误,这取决于用户输入的是什么: if ($search_Text =~ /$user_Pattern/) { 上一篇:CGI编程的安全性 -- 文件名 下一篇:windows下Perl开发环境的安装和配置 更多相关文章
|
推荐文章
精彩文章
|