5.0 -安全
———————————————————————-
q5.1: 以 perl 写成的 cgi 程式是不是不如以 shell 或 c
写的来得安全?
这个问题的答案是: cgi
程式先天上就不安全,不管它是用那个语言写成的*。
【译者□
www 及 cgi 操作安全 faq
(<http://www-genome.wi.mit.edu/www/faqs/www-security-faq.html>)
中问题第 31 对此有深入的探讨。
———————————————————————-
q5.2:我该特别留意哪些安全事项?
绝对不要对 shell 暴露任何 form 资料。底下这几项通通都是安全漏洞:
* open(command, "/usr/ucb/finger $form_user");
* system("/usr/ucb/finger $form_user");
* @data = `usr/ucb/finger $form_user`;
话虽如此,在上面的第二种写法中,系统安全可藉著改变参数传送的方式而得以
改善。也就是将参数由字串方式传送(shell
会先解译),改为序列方式传
送。
system("/usr/ucb/finger", $form_user);
您同时应该阅读:
* 由 lincoln stein 所著,一份很完整的 www 及 cgi 操作安全 faq
(<http://www-genome.wi.mit.edu/www/faqs/www-security-faq.html>
* paul phillips 所著,cgi 安全 faq
(<http://www.cerf.net/~paulp/cgi-security/safe-cgi.txt>
———————————————————————-
q5.3:为什麽大家都说
http://bigidiot.abuse-me.com/perl.exe?foo.pl
这样很危险?会有多糟?
极度危险!想想看如果我这麽做会发生什麽事:
http://bigidiot.abuse-me.com/cgi-bin/perl.exe?-e+format:%20c
现在您同意了吧?避免这个恶梦发生的方法:
* 将 perl.exe 执行档由 “cgi-bin 移到 server
根目录以外的目录里
去。
* 在 “cgi-bin 里用批次档 (batch) script 来叫出您的 cgi
script。
以下是一例。假设您的 cgi script 叫做 “sample.pl 而您的批次档叫
“simple.bat:
@echo off
c:\dos_perl\perl.exe
c:\netscape\ns-home\docs\cgi-bin\simple.pl
现在,您可以做:
<a href="/cgi-bin/simple.bat">click here</a>
———————————————————————-
q5.4:要如何在程式中安全地使用逆向撇号(backticks,"`",位於键盘左上
角)?这麽做:
@ans = `grep$user_field some.file`;
是不是真的不安全?
是的!这非常危险!试想,如果 $user_field 含有这样的内容会有什麽後
果:
; rm -fr / ;
要达到相同的效果,一个比较安全的做法是*:
if (open grep, "-|") {
@ans = <grep>
} else {
exec("/usr/local/bin/grep", $user_field, "some.file")
|| die "error execing command", "\n";
}
close grep;
【译者】如果读者对以上 open grep, "-|"部份的句法有疑问,可
以参阅 perlipc manpages 中 safe pipe opens一节的说明。
———————————————————————-
q5.5: /$user_variable/ 这个句法是不是 perl 5 中的一个安全漏洞?
不!这不是个安全漏洞。但是如果您用 eval 指令在执行期 (runtime)
去评估
这个叙述,那麽,它会变成一个安全死角。例如这种做法可能很危险:
foreach $regexp (@all_regexps) {
eval "foreach (\@data) { push(\@matches, \$_) if
m|$regexp|o; }";
}
———————————————————————-
这个叙述,那麽,它会变成一个安全死角。例如这种做法可能很危险:
foreach $regexp (@all_regexps) {
eval "foreach (\@data) { push(\@matches, \$_) if
m|$regexp|o; }";
}