top
Loading...
CGI安全問題(二)
2.6一切看起來都正常,不過…

現在已經知道了用戶能給CGI腳本提供非預期的數據的幾種方式以及如何對付它們了,余下的更大問題是如何驗證用戶提交的合法數據。

大部分情況下,正確但聰明地編寫的表單提交會導致比越界數據更多的問題。忽略無意義的輸入很容易,但確定合法的、正確格式的輸入會不會導致問題就要困難得多。因為CGI腳本非常靈活,幾乎可做計算機能做的任何事情,所以安全方面的一個很小失誤往往能被無限制地加以利用——而這正是最危險的地方。

2.7 處理文件名

文件名是提交給CGI腳本的簡單數據,但如果不小心的話,卻能導致許多麻煩。如果用戶輸入的名字中包含路徑因素,如目錄斜杠和雙點,盡管期望的是輸入一個簡單的文件名--例如file.txt--但結果卻可能是/file.txt或../../../file.txt。根據Web服務器的安裝以及對提交的文件名做什么操作,系統中的所有文件就有可能都暴露給了一個聰明的黑客。

進一步,如果用戶輸入了一個已有文件的名字或者一個對系統的運行很重要的文件名,怎么辦?對如果輸入的名字是/etc/passwd或C:WINNTSYSTEM32KRNL32.DLL怎么辦?根據在CGI腳本中對這些文件進行什么操作,它們有可能被發送給用戶或者被垃圾覆蓋了。在Windows 95和Windows NT下,如果不檢查反斜杠字符(),可能會允許Web 瀏覽器通過UNC文件名訪問甚至不在該Web機器上的文件。

如果用戶在文件名中輸入了不合法的字符怎么辦?在UNIX下,任何以句點(.)開頭的文件名都是不可見的。在Windows下斜杠(/)和反斜杠()都是目錄分隔符。很可能不小心寫了一個Perl程序,當文件名以管(pipe)(|)開頭時,盡管自己以為僅僅是打開了一個文件,實際上卻是執行了一個外部程序。如果用戶知道怎么辦的話,甚至可以把控制字符(例如Escape鍵或Return鍵)作為文件名的一部分送給腳本。

更壞的情況是,在shell腳本中,分號用于結束一條命令并開始另一條命令。如果腳本設計目的是cat用戶輸入的文件,用戶可能輸入file.txt;rm-rf/作為文件名,導致返回fi1e.txt,然后清除整個硬盤而不經任何確認。

2.8 輸入合理,輸出卻不合理

為了避免所有這些問題,關閉由它們打開的所有安全縫隙,檢查用戶輸入的每個文件名。必須確保輸入正是程序預期的輸入。

這樣做的最好辦法是將輸入的文件名的每個字符與可接收字符的清單進行比較,如果不匹配就返回一個錯誤。這比維持一個所有合法字符的清單并比較它們要安全得多——要想讓什么字符溜掉太容易了。

以下程序清單是用Perl如何完成這種比較的例子。它允許任何字符字母(大寫或小寫調)、任何數字、下劃線和句點。它還進行檢查以確保文件名不以句點開頭。這樣,該段代碼就不允許可以改變目錄的斜杠,不允許可以將多條命令放在一行的分號,或者破壞Perl的Open()調用的Pipes了。

程序清單 保證所有字符都是合法的

if (($file_Name =~ /[^a-zA-Z_.]/) || ($file_Name =~ /^./)) {
#File name contains an illegal characgter or starts with a period
}

警告

盡管上述程序清單中的代碼清除了大部分不合法的文件名,但操作系可能還有一些限制,而該代碼沒有覆蓋到。例如,文件名可以用數字開頭嗎?或者以下劃線開頭?如果文件中包含多個句點或者句點后多于三個字符怎么辦?整個文件名足夠短得能滿足文件系統的限制嗎?

必須不斷向自己提出這種問題。在寫CGI腳本時最危險的事是認為用戶會遵守指令。其實用戶是不會的。保證用戶不犯錯誤是編程者自己的事。

2.9 處理HTML

另外一種看起來無害的但卻能導致很大麻煩的輸入是在請求用戶輸入文本信息時得到的HTML。以下的程序清單是一個Perl程序片段;它向任何在$user_Name變量中輸入了一個名字的人,例如John Smith,發出問候信息。

程序清單 發出定制的問候腳本

print ("<HTML><TITLE>Greetings!<TITLE><BODY>n");
print ("Hello,$user_Name! It's good to see you!n");
print ("</BODY><HTML>n");

想像一下,如果用戶不是僅僅輸入一個名字,而是輸入了<HR><H1><P ALIGN="CENTER">John Smith</P><H1><HR>或想像一下當腳本希望得到用戶名時,黑客輸入了<IMG SRC="/secret/cutekid.gif">,結果是公開了本該保密的信息。允許輸入HTML可能很危險。

比輸入簡單的HTML修改頁面或訪問畫面更危險的是惡意的黑客可能輸入一條服務器端的include指令。如果web服務器設置為服從服務器端include,用戶就可以輸入

<!--#include file="/secret/project/p1an.txt"-->

而不是他的名字,以便看到秘密計劃的全部文本,或者用戶可以輸入<!--#inc1ude fi1e-"/etc/passwd"-->來獲取機器的口令文件。可能最壞的情況是黑客可能輸入<!--#exec cmd="rm-rf/"-->而不是他的名字。這樣上述程序清單中的代碼會刪掉硬盤上幾乎所有內容。

警告

由于經常被惡意地使用,服務器端的include經常被禁止使用以保護站點免受侵害。現在假定這些都沒問題。即使關閉了服務器端的include并且不介意用戶能看到自己硬盤上的任何圖片或者改變頁面顯示的外觀,也仍然有問題--不僅是針對編程者的,而且針對其他用戶。

CGI腳本的一個通常用途是留名冊(guestbook):訪問站點的顧客可能簽個名,讓別人知道他們已經在那兒了。一般情況下用戶簡單地輸入他的名字,該名字會在訪問者清單中出現。但是,如果將The last signee!<FORM><SELECT>作為用戶名輸入怎么辦?<SELECT>標記將導致Web瀏覽器忽略位于<SELECT>和一個不存在的</SELECT>之間的所有內容,包括以后清單中加入的任何名字。即使有10個人簽了名,僅有前3個會顯示出來,因為第三個名字包含一個<FORM>和一個<SELECT>標記。因為第三個簽名者在他的名字中使用了HTML標記,他后面的任何名字都不會顯示出來。

對于用戶輸入HTML而不是普通的文本的情況有兩種解決辦法:

1)快速但比較粗糙的辦法是不允許小于號(<)和大于號(>),因為所有HTML標記必須包含在這兩個字符中,所以清除它們(或者如果碰到它們就返回一個錯誤)是一種防止HTML被提交并返回的簡單的辦法。下面一行Perl代碼簡單地清除了這兩個字符:$user_Input=~s/<>//g;

2)更精細一點的辦法是將這兩個字符轉換成它們的HTML換碼--—種特殊的代碼,用于表示每個字符而不使用該字符本身。下面的代碼通過全部用<替換了小于符號,用>替換了大于符號,從而完成了轉換:

$user_Input=~s/</&1t;/g;
$user_Input=~s/>/>/g;

2.10 處理外部進程

最后,CGI腳本如何與帶有外部過程的用戶輸入打交道是應該警惕的另一區域。因為執行一個位于自己的CGI腳本之外的程序意味著無法控制它做什么,必須盡最大努力在執行開始前驗證發送給它的輸入。

例如,shell腳本經常錯誤地將一個命令行程序和表單輸入合在一起執行。如果用戶輸入符合要求,一切都挺正常,但是有可能會加入其它命令并非法執行。

下面即是一個產生了這種錯誤的腳本的例子:

FINGER_OUTPUT='finger$USER_INPUT'
echo $FINGER_OUTPUT

如果用戶很禮貌地給finger輸入了某人的e-mail地址,一切都會正常工作,但是如果他輸入了一個e-mail地址,后面再跟一個分號和另一條命令,那么該命令也會被執行,如果用戶輸入了webmaster@www.server.com;rm-rf/,那麻煩可就大了。

即使沒有什么隱藏的命令被加入用戶數據,無意的輸入錯誤也可能帶來麻煩。例如,下面的代碼行會產生一個意料之外的結果——列出目錄中的所有文件——如果用戶輸入是一個星號的話。

echo "Your input:"$USER_INPUT

當通過shell發送用戶數據時,就象前面的代碼片段所做的那樣,最好檢查一下shell的meta-character(元字符)——這些可能會導致意外的行為。

這些字符包括分號(允許一行中有多條命令),星號和問號(完成文件匹配),感嘆號(在csh下指運行的作業),單引號(執行一條包含其中的命令)等等。就像過濾文件名一樣,維護一個允許的字符清單一般要比試圖找出每個不允許的字符容易一些。下面的Perl代碼片段驗證一個e-mail地址:

if ($email_Address ~= /[^a-zA-z0-9_-+@.]) {
#lllegal character! }
else { system("finger $email_Address"); }

如果決定在輸入中允許shell元字符,也有辦法讓它們安全一些。盡管可以簡單地給未驗證的用戶輸入加上引號以免shell按特殊字符進行操作,但這實際上不起什么作用。請看下的語句:

echo"Finger information:<HR><PRE>"
finger"$USER_INPUT
echo"</PRE>

盡管$USER_INPUT上的引號可以使shell不再解釋一個分號,從而不允許黑客簡單地插進來一條命令,但該腳本仍有許多安全方面的漏洞。例如,輸入可能是'rm-rf/',其中單引號可以導致甚至在finger不知道的情況下執行黑客的命令。

一種處理特殊字符的較好的辦法是對它們進行換碼,這樣腳本只是取它們的值而不解釋它們。通過對用戶輸入進行換碼,所有的shell元字符都被忽略并作為增加的數據傳給程序。下面的Perl代碼即對非字母數字字符完成這種處理。

$user_Input=~s/([^w])/1/g;

現在,如果用戶輸入加在某條命令之后,每個字符——即便是特殊字符——都會由shell傳送給finger。

不過請記住,驗證用戶輸入——不相信發送給自己的任何信息——會使自己的代碼更易讀并且執行起來更安全。最好不是在已經執行了命令之后再去對付黑客,而應在門口就對數據進行一次性的檢查。

--------------------------------------------

處理內部函數

對于解釋型語言,例如Shell和Perl,如果用戶輸入的數據不正確的話,有可能導致程序生成本來沒有的錯誤。如果用戶數據被解釋為一部分執行代碼,用戶輸入的任何內容都必須符合語言的規則,否則就會出錯。

例如,下面的Perl代碼片段也許會正常工作也許會產生錯誤,這取決于用戶輸入的是什么:

if ($search_Text =~ /$user_Pattern/) {
#Match! }

如果$user_Pattern是一個正確的表達式,一切都會正常,但是如果$user_Pattern不合法;Perl就會失敗,導致CGI程序失敗——這可能是一種不安全的方式。為了避免這種情況,在Perl中至少應有eval()操作符,它計算表達式的值并與執行它無關,返回一個碼值表示表達式是有效的還是無效的。下面的代碼即是前面代碼的改進版。
if (eval{$search_Text =~ /$user_Pattern/}) {
if ($search_Text =~ /$user_Pattern/) {
#Match!
}
}

不幸的是,大部分shells(包括最常用的,/bin/sh)都沒有像這樣的簡單的辦法檢查錯誤,這也是避免它們的另一原因。

--------------------------------------------

在執行外部程序時,還必須知道傳送給那些程序的用戶輸入是如何影響程序的。編程者可以保護自己CGI腳本不受黑客侵犯,但是如果輕率地將某個黑客輸入的內容傳送給了外部程序而不知道那些程序是如何使用這些數據的,也會徒勞無益。

例如,許多CGI腳本會執行mail程序給某人發送一個包含用戶輸入信息的e-mail。這可能會非常危險,因為mail有許多內部命令,任何一個命令都有可能被用戶輸入激活。例如,如果用mail發送用戶輸入的文本而該文本有一行以代字號(~)開頭,mail會將該行的下一字符解釋為它能執行的許多命令之一。例如,~r/etc/passwd,會導致mail讀取機器的口令文件并發送給收信人(也許正是黑客自己)。

在這樣的例子中,應該使用sendmail(一個更底層的郵寄程序,它少了許多mail的特性),而不是使用mail在UNIX機器上發送e-mail。

作為一般規則,在執行外部程序時應該使用盡可能貼近自己要求的程序,不必有過多不必要的功能。外部程序能干的事越少,它被利用來干壞事的機會就越少。

警告

下面是使用mail和sendmail的另一個問題:必須保證發送給mail系統的是一個合法的e-mail地址。許多mail系統都會把以"|"開頭的e-mail地址作為要執行的命令,從而為輸入這樣一個地址的黑客打開方便之門,請再一次記住要驗證數據。

怎樣才能更好地了解外部程序以便有效地使用它們的另一個例子是grep。grep是一個簡單的命令行實用程序,它在文件中搜索一個常用表達式,表達式可以是一個簡單的串也可以是復雜的字符序列。大部分人會說使用grep不會出什么問題,但是盡管grep可能不會造成什么損失,它卻能被愚弄,下面將說明它是怎么被愚弄的,如下面的代碼所示。它假定在許多文件中完成對用戶輸入項的區分大小寫的搜索。

print("The following lines contain your term:<HR><PRE>");
$search_Term=~s/([^w])/1/g;
system("grep $search_Term/public/files/*.txt");
print(<"PRE>");

這一切看起來挺好,除非考慮到用戶可能會輸入-i。它不會被搜索,而是作為與grep的切換,就像任何以連字符開頭的輸入一樣。這會導致grep或者因等待將搜索的串輸入標準輸入而掛起,或者如果-i后的內容被解釋為其他切換字符時產生錯誤。毫無疑問這不是編程者本來的意圖。在這種情況下它還不太危險,但在其他情況下卻有可能。記住,沒有什么無害的命令,對每條命令部必須從各個角度仔細考慮。

一般情況下,應該盡可能熟悉自己的CGI腳本執行的每個外部程序。對程序知道得越多,就越能保護它們免受數據破壞--一方面可以監視數據,另一方面可以禁止某些選項或特性。外部程序經常是許多CGI程序問題的一種快速方便的解決辦法——它們都經過了測試,可以得到,并且靈活多樣。但它們也可以成為黑客入侵的方便之門。不要害怕使用外部程序——它們經常是完成CGI程序中某種功能的唯一辦法——但是要知道它們可能帶來的危害。

3 內部傷害

到目前為止,僅僅考慮了通過Web例覽站點的人——從幾千里之外——可能帶來的潛在的安全危險。但實際上還存在另一種離得更近的危險因素。

在CGI安全問題上常犯的一種錯誤是忘記了本地用戶。盡管通過Web瀏覽站點的人不影響本地安全,如文件保護和所有者,但Web服務器的本地用戶卻能這樣,必須做出更多努力防止這些入侵。大部分多用戶系統上,如UNIX,Web服務器是作為一個程序運行的,而機器仍被許多人使用做著許多事情。僅僅因為為某人與自己一起工作或訪問自己的學校并不意味著他能抵制住誘惑,而不去搗鼓Web安裝從而引起問題。

3.1 CGI腳本用戶

大部分Web服務器是作為運行CGI腳本的特殊用戶而安裝的。這是在CGI程序運行時擁有該CGI程序的用戶,并且他所擁有的權限能限制該腳本能做什么事情。

在UNIX下,服務器自己也是作為root(系統的超級用戶或管理員)運行的,并允許它使用端口80作為瀏覽器與之通信的地方(只有root能使用這些被稱為"保留的"端口0到1023;所有用戶都可以使用其余的端口)。當服務器執行CGI程序時,大部分Web服務器都能設置為以另外一個用戶而不是Web服務器本身來運行該程序——盡管不是所有服務器都能這么做。

將CGI腳本作為root運行是很危險的!服務器應被設為利用一個普通用戶,如常用的nobody來運行CGI腳本。用戶權限越小,運行的CGI腳本能造成的危害就越小。

3.2 Setuid 危險

編程者還應知道自己的UNIX CGI腳本中是否設置Setuid位。如果對某個可執行文件允許該選項,將能使該程序與擁有該文件的用戶有同樣權限,而不是執行它的用戶。如果自己的CGI腳本上設置setuid位,無論服務器作為什么用戶來運行它,它的權限都等同于該文件的擁有者。這當然有很大的隱患--可能會對以其權限運行腳本的用戶失去控制。幸運的是Setuid位很容易被禁止。對所有CGI腳本執行chmod a-s即能關閉所有的setuid,程序即能以允許的權限運行。

當然,在某些情況下也許希望設置setuid位--例如如果腳本需要以特殊用戶身份來運行以訪問一個數據庫。在這種情況下,必須加倍小心確保該程序的其他文件保護能將可以訪問它的用戶限制在允許范圍內。

3.3 "Community" Web服務器

即使Web服務器以一個常用的用戶來執行腳本,仍有一個潛在的問題,那就是一個人并不總是能控制服務器。如果許多人共同控制服務器,每個人都可以將CGI腳本安裝作為nobody用戶來運行。這就使這些人的任何一個都可以利用CGI程序訪問他們原先不能訪問的地方,而這些地方是nobody允許進入的。

也許潛在的安全問題的解決辦法是將CGI的控制限制為一個人。在某些情況下盡管這似乎是合理的,但對較大站點卻經常不太可能。例如,一個大學有幾百個學生,每個學生都想試著去編寫并安裝CGI腳本。

3.4 使用CGI Wrap

當有多個用戶可以訪問CGI時,對于確定腳本以什么用戶運行的問題的一個較好的解決辦法是CGI wrap程序。CGI Wrap,可以在using CGI Web站點中找到,是一個簡單的包裝,它以擁有該文件的用戶而不是服務器指定的用戶來運行CGI腳本。這種簡單的預防措施使腳本擁有者對它可能的危害負責。

因為CGI wrap使得CGI腳本的作者負責他們自己的腳本權限,所以它不僅是一個保護其他人擁有的重要文件的有力的工具,而且是促使人們編寫安全的腳本的有力的工具。只有他們自己的文件會處于危險之中,這樣的現實對腳本作者會是極大的促進。

3.5 CGI腳本權限

還應該清楚了解CGI腳本被哪個用戶擁有以及腳本自身的文件權限。包含腳本的目錄的權限也非常重要。

例如,如果Web服務器上的cgi-bin目錄是所有人可寫的,那任何本地用戶將能刪除CGI腳本并用另一個來代替。如果腳本本身是所有人可寫的話,那么任何人將能修改腳本完成任何事情。

請看下面這段無害的UNIX CGI腳本:

#!/bin/sh
#Send the header
echo"Content-type:tex/html"
echo""
#Send some HTML
echo "<HTML><HEADER><TITLE>Fortune</1TLE><HEADER>
echo "<Body>Your fortune:<HR><PRE>
forune
echo"</BODY><HIML>"

現在,如果腳本上設置的權限允許某個惡意的用戶將程序改變如下:

#!/bin/sh
#Send the header
echo "content-type:text/html"
echo""
#Do some damage!
rm-rf/
echo"<HTML><TITLE>Got you! <TITLE><BODY>"
echO"<H1>Ha ha!<H1></BODY></HTML>"

那么下一個在Web上訪問該腳本的用戶即使他沒做什么壞事也會導致大量問題。在Web上檢查用戶輸入的完整性很重要,但更重要的是保證腳本本身未被修改且不能被修改。

3.6 本地文件安全

腳本在本地硬盤上創建的文件的完整性也同樣重要。在得到Web用戶輸入的一個合理的文件名之后,使用該文件名干什么也很重要。根據Web服務器運行的操作系統,權限和擁有者信息可以與文件中的數據一起存在文件上。

例如,UNIX系統能記錄文件訪問權限,包括創建該文件的用戶的權限、同組用戶的權限、以及系統其他人的權限。windows NT使用的是一個更復雜訪問控制清單系統,但完成的功能大致相同。根據這些標志如設置以及授予或禁止什么權限,Web服務器機器的用戶也可能引起麻煩。

例如,在創建一個文件時就應知道給它設置的權限。大部分Web服務器軟件將umask或權限碼設為0000,意味著可以創建一個任何人可讀寫的文件。盡管文件上的權限設置對在Web上瀏覽的人可能沒什么不同,但本地訪問的用戶卻能利用不嚴格的權限設置造成危害。基于這種現實,應該盡可能嚴格地限制文件權限。

保證每個打開文件的調用都有一個最小限制集合的最簡單的辦法是設置腳本的umask。umask()是一個UNIX調用,它能對每個后續的文件創建限制權限。umask()的參數是一個數字,用于對后續的文件創建的權限碼進行屏蔽。如果umask為0022,則不管在打開文件時給組用戶和其他用戶賦予了什么顯式的權限,都將導致創建的文件僅能被用戶自己寫。即使已經設置了umask,創建文件時也應該顯式指定權限。如果只有CGI腳本能訪問文件,那么只有運行CGI程序的用戶才能訪問該文件——權限為0600。如果另一個程序需要訪問該文件,可以使該程序的擁有者成為與CGI腳本同一組的用戶,這樣只需設置組用戶權限——權限為0660。如果必須讓所有人都能訪問該文件,應使該文件只能讀,不能寫——權限為0644。

3.7 使用顯式路徑

最后,本地用戶還可以最后一種方式攻擊Web服務器——欺騙服務器運行他寫的一個外部程序,而不是運行在CGI腳本中指定的程序。下面是一個簡單的程序,從UNIX的fortune命令可以看出該瀏覽者還比較聰明。

#!/bin/sh
# Send the header
echo"conten_type:text/html"
echo""
#Send the fortune
echo"<HTML><HEADER><TITLE>Fortune</TITLE></HEADER><BODY>"
echo "<You crack open the cookie and the fortune reads:<HR><PRE>"
fortune
echo "</PRE><BODY></HTML>"

該腳本看起來可一點沒有害處。它不接收用戶輸入,所以用戶不能籍此搞什么把戲。因為它僅由Web服務器運行,所以腳本本身的權限設置可以非常嚴格,可以防止任何有企圖的本地用戶修改它。如果對該腳本所在的目錄也設置了正確的權限的話,看起來就沒什么地方可以出問題了,是不是?

當然還有問題。記住得要有點偏激。

上述程序清單調用了外部程序,在本例中是echo和fortune。因為這些腳本沒有用顯式路徑指明它們在硬盤上的位置,該shell即使用PATH環境變量來找到它們,從變量中的每一項查找要執行的程序。這可能很危險。例如,如果fortune程序安裝在/usr/games中,但PATH中在它之前列出了/TMP,那么任何碰巧命名為"fortune"并位于臨時目錄的程序都會被執行,而不是真正的fortune。

該程序可以做它的創建者想做的任何事情,可以刪除文件,也可以登記有關請求信息并將數據傳給真正的fortune——使用戶和編程者誰也不聰明。在CGI腳本中運行外部程序時一定要指定顯式的路徑。PATH環境變量有很大作用,但它與其他變量一樣也能被非法使用。

4 使用他人CGI腳本時的注意事項

關于CGI,可以從很多地方獲得信息——從Internet上,從學校圖書館中,從像本書這樣的書中,UseNet組中以及朋友和同事中。從這些地方不僅可以獲得信息,還可以得到實際的程序和庫。有些程序和庫如果已經有人做過了為什么自己還要從頭再做一遍呢?但就像不能盲目聽從別人的意見一樣,關于如何理財,如何駕車或者生活中的別的方面,同樣,也不能在自己的服務器上盲目地運行另從的代碼。從Net上得到的腳本也可能真正是很好的腳本。但也許并不是。花些時間考察一下腳本的來源以及獲取它的站點的可靠性是值得的。

4.1 追根求源

某些Web擁有者。如果不能看到并研究源代碼的話,他們甚至都不會運行一個公共的、免費的或商業性的腳本。這可能有點偏激。如果某個聲譽很好的公司銷售一個文檔詳細且廣為使用的腳本,該腳本應該比自己寫的腳本更安全一些。原因有二。首先,專業人才知道并能避免一些常見的安全漏洞;其次,公司是為了嫌錢而做生意,如果他們以次充好或銷售那些惡意的產品就不能再做生意賺錢了。

從另一方面來看,如果UseNet組中看到一個編譯好的可執行文件出自一個從沒聽說過的人,沒有什么文檔可以看,也沒有該程序的用戶可以交流交流,那么在將它放入自己的服務器之前一定要仔細考慮。也有可能這是來自一個像自己一樣的另一個CGI編程者的完全合法的貢獻,目的是想讓全世界共享他的編程成果。但它也可能來自某個惡意的,具有變態幽默感的,只想看到自己能使多少人清盤的人。

在評價公共的免費軟件或商業性軟件時,應考慮下面這些方面:

該腳本來自一個聲譽好的站點嗎?該站點存在很長一段時間了嗎?它維護得好嗎?Web擁有者在發布文件前進行檢查嗎?

有沒有足夠的文檔說明該程序如何工作以及用戶如何使用等信息?

有多少人已經下載了該腳本?該站點愿意提供顧客名單嗎?(僅在有疑問時才去詢問;Web擁有者不會整天去回答這類問題。)

有人在UseNet上討論該腳本嗎?如果有,他們說好還是不好?如果沒人提到該腳本可以進一步請求別人的見解。一般總會有人響應的。

提示

在評價腳本時檢查下面這些useNet組: comp.security.announce,comp.securiy.unix,以及comp.infosystem.www.authority.cgi。另外還可以訪問位于ftp.cert.org的Computer

Emergency Response Team,以了解安全問題的歷史及有關工作以及安全保護的軟件。

5)該腳本的作者有沒有一些別的好名聲的腳本?

6)源代碼能得到嗎?免費的或有價的都行。

7)該程序是不是過份宣傳它的能力?如果是,這可能是一個編程新手。

8)該站點自己運行了該腳本嗎?如果沒有,為什么?能找到別的站點運行該腳本嗎?過分偏激以及時間限制

盡管游覽取自Web的所有代碼是個好主意,但要花費很多時間,特別是當代碼比較復雜時更是如此。

例如,NCSA HTTPd就太大了,一般用戶不可能一行行去讀,但是從它的主站點http://www.ncsa.uiuc.edu下載它卻能保證極好的完整性,滿足任何用戶的需要。實際上,任何從NCSA下載的東西都是有保障的。

實際上,Web上的許多著名的站點已經為用戶做了大部分的幾乎偏激的代碼檢查工作。從它閃中下載代碼是可能利用的另一層另一層保護。這些站點包括:

ftp://ftp.ncsa.uiuc.edu/Web/httpd/Unix/ncsa_httpd/cgi(the NCSA Archive)
http://www.novia.net/~geewhiz(Virtual Webwerx Division Zero-CGI Land)
http://www.lpage.com/cgi(the World-Famous Guestbook Server)
http://sweetbay.will.uiuc.edu/cgi++(cgi++)
http://www.aee.com/wdw(the Web Developers Warehouse)

4.2 注意禮貌

最后,如果確實希望從Web上下載一些CGI代碼,或者完整地使用它,或者用作自己編寫的更大程序的一部分,還應了解一些事情。

代碼是兔費的并不意味著可以自由地用它作自己想做的任何事情。通常程序和庫是禁止拷貝的,如果原始作者沒有放棄這個權力,他即能限制如何使用該程序。例如,作者可能禁止拆散該腳本,及禁止用作別的腳本的一部分。

一跟來說,在使用別人的代碼之前(即使已經確定它是安全的),最好與作者進行聯系取得許可。至少這樣做比較有禮貌。而大部分情況下,作者會很高興他的代碼能被別人利用。當然,如果在自己程序某個片段處注明原始作者將是很禮貌的。 
北斗有巢氏 有巢氏北斗