[ 永远的UNIX::UNIX技术资料的宝库 ]

首页 > 网络安全 > 程序 > 正文

如何撰写安全的CGI程式

来源:本文出自:http://www.cert.org.tw 作者: (2001-11-02 08:00:01)


前言
在我们(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,如此可避免掉上述问题。


(http://www.fanqiang.com)



 
 相关文章

★  感谢所有的作者为我们学习技术知识提供了一条捷径  ★
www.fanqiang.com