|
|
※阅读文章※ |
如何撰写安全的CGI程式作者:不祥 [文章出自: www.fanqiang.com] 前言 在我们(TWCERT)曾经遇过的WEB网站入侵事件里,有部份的原因是撰写了不安全的 CGI程式,然而要撰写安全的CGI程式,其实不是一件很困难的事,在此将心得与大家分 享,本文主要以UNIX上的Web伺服器环境为主,若您有任何疑问,欢迎来信讨论,我的 电子邮件信箱为: changiz@cert.org.tw。 1.CGI程式撰写方面 (1)传入的参数方面 *检查传入的参数* 不要认为你所收到的资料一定是正确的。一般攻击者会试着传送假资料,即使你将 所有可传回的值,用选单方式让使用者选取,攻击者依然可传送你预期外的资料给 CGI程式。 另外,使用"POST"的传输方式并不比用"GET"方式为安全,只是在浏览器上看不到传 输资料罢了,仔细想想,你要传给CGI的参数是不是都写在HTML档里呢?那麽,即 使你用"POST"的方式传资料,攻击者只要写一些小程式,依然可假造传输资料。再 者,HIDDEN形态的参数(如下)也是一样的道理。 <input type="hidden" name="env_report" value="REMOTE_HOST"> 千万别以为type="hidden"是绝对安全的。 所以呢,切记检查传回的参数,以确定是否为合法的资料。 *不要传入目录或档案名称* 若你欲使用CGI修改数个档案或目录,切记不可传递档名,因为入侵者可以传送你预 期外的档名给CGI程式,所以最好以代号传送给CGI程式,让CGI依代号找出对应的 档名。 另外,假如必须传送档案名或目录名,必须注意"../"(上层目录)的检查,举例来说, 假如你的CGI目录为/web/cgi-bin/,而你传回的档名"/test.dat"表示系统绝对路 径为"/web/cgi-bin/test.dat"的档案,此时若入侵者传回"../log/logs"而CGI程式 没做检查,入侵者就可能修改到"/web/log/logs"这个档。 (2)程式的缓区长度 如果程式没检查存放资料的记忆体长度,是否能完全存放传入资料,那就可能被攻击者 以Buffer overflow攻击。所以,当你要存放传入资料时,不彷参考以下程式(C语言): file://使用POST方法传递资料时的资料读取 int bfsize=atoi(getenv("CONTENT_LENGTH")); file://取得资料长度 char* data_string = (char*) malloc(bfsize); file://取得适当的记忆体 if (data_string != NULL) read(STDIN,data_string,bfsize); file://将资料存放於记忆体中 当然,你也可以检查资料长度是否超过你的缓区大小,如果超过的话, 就结束程式,这样也可以避免Buffer Overflow攻击。 (3)锁定写入的资料档 这是一般的问题,通常在资料库上都会碰到,亦即当可能有多个使用者同时存取档案 时,为了避免资料写入错误与达到资料的一致性,都必须做锁定(Lock)的动作。 2.CGI程式系统设定方面 (1)开放CGI於任何目录的注意事项 Server中有个(AddHandler cgi-script .cgi)设定,可将每个目录中的*.cgi都当成 CGI程式执行。若你开启了这个设定,而你的伺服器又允许每个使用者再自己的目录 下撰写网页,并且网页拥有者与Web Server的执行者相同,那就有可能被使用者藉 由CGI程式来修改网页。解决方法是不要让档案目录的拥有者与WEB伺服器的执行者 相同。例如Web Server执行时会变成"nobody",那就可以将网页资料的拥有者设成 "root",或是其它不是"nobody"的帐号。 (2)CGI程式的Setuid属性的使用 注意是否有setuid的CGI程式存在,一般的情况下是不需要setuid的。 当然有些情形是例外,比方你允许所有使用者能存放CGI程式於使用者目录,而你的网 页又提供CGI所做的留言板,此时使用者可能透过自己写的CGI程式,来修改甚至置换 整个留言板内容,此时你就可以将留言板的CGI程式拥有者改成另一个使用者帐号(千 万别用root),并开启setuid,如此可避免掉上述问题。 文章加入时间: 2004-11-17 15:01:52 责任编辑: w9 (2349 人次查阅) |