CGI教學:CGI安全問題(7)
發(fā)表時間:2023-12-26 來源:明輝站整理相關軟件相關文章人氣:
[摘要]3 內(nèi)部傷害 到目前為止,僅僅考慮了通過Web例覽站點的人——從幾千里之外——可能帶來的潛在的安全危險。但實際上還存在另一種離得更近的危險因素。 在CGI安全問題上常犯的一種錯誤是忘記了本地用戶。盡管通過Web瀏覽站點的人不影響本地安全,如文件保護和所有者,但Web服務器的本地用戶卻能這樣,必須做...
3 內(nèi)部傷害
到目前為止,僅僅考慮了通過Web例覽站點的人——從幾千里之外——可能帶來的潛在的安全危險。但實際上還存在另一種離得更近的危險因素。
在CGI安全問題上常犯的一種錯誤是忘記了本地用戶。盡管通過Web瀏覽站點的人不影響本地安全,如文件保護和所有者,但Web服務器的本地用戶卻能這樣,必須做出更多努力防止這些入侵。大部分多用戶系統(tǒng)上,如UNIX,Web服務器是作為一個程序運行的,而機器仍被許多人使用做著許多事情。僅僅因為為某人與自己一起工作或訪問自己的學并不意味著他能抵制住誘惑,而不去搗鼓Web安裝從而引起問題。
3.1 CGI腳本用戶
大部分Web服務器是作為運行CGI腳本的特殊用戶而安裝的。這是在CGI程序運行時擁有該CGI程序的用戶,并且他所擁有的權限能限制該腳本能做什么事情。
在UNIX下,服務器自己也是作為root(系統(tǒng)的超級用戶或管理員)運行的,并允許它使用端口80作為瀏覽器與之通信的地方(只有root能使用這些被稱為"保留的"端口0到1023;所有用戶都可以使用其余的端口)。當服務器執(zhí)行CGI程序時,大部分Web服務器都能設置為以另外一個用戶而不是Web服務器本身來運行該程序——盡管不是所有服務器都能這么做。
將CGI腳本作為root運行是很危險的!服務器應被設為利用一個普通用戶,如常用的nobody來運行CGI腳本。用戶權限越小,運行的CGI腳本能造成的危害就越小。
3.2 Setuid 危險
編程者還應知道自己的UNIX CGI腳本中是否設置Setuid位。如果對某個可執(zhí)行文件允許該選項,將能使該程序與擁有該文件的用戶有同樣權限,而不是執(zhí)行它的用戶。如果自己的CGI腳本上設置setuid位,無論服務器作為什么用戶來運行它,它的權限都等同于該文件的擁有者。這當然有很大的隱患--可能會對以其權限運行腳本的用戶失去控制。幸運的是Setuid位很容易被禁止。對所有CGI腳本執(zhí)行chmod a-s即能關閉所有的setuid,程序即能以允許的權限運行。
當然,在某些情況下也許希望設置setuid位--例如如果腳本需要以特殊用戶身份來運行以訪問一個數(shù)據(jù)庫。在這種情況下,必須加倍小心確保該程序的其他文件保護能將可以訪問它的用戶限制在允許范圍內(nèi)。
3.3 "Community" Web服務器
即使Web服務器以一個常用的用戶來執(zhí)行腳本,仍有一個潛在的問題,那就是一個人并不總是能控制服務器。如果許多人共同控制服務器,每個人都可以將CGI腳本安裝作為nobody用戶來運行。這就使這些人的任何一個都可以利用CGI程序訪問他們原先不能訪問的地方,而這些地方是nobody允許進入的。
也許潛在的安全問題的解決辦法是將CGI的控制限制為一個人。在某些情況下盡管這似乎是合理的,但對較大站點卻經(jīng)常不太可能。例如,一個大學有幾百個學生,每個學生都想試著去編寫并安裝CGI腳本。
3.4 使用CGI Wrap
當有多個用戶可以訪問CGI時,對于確定腳本以什么用戶運行的問題的一個較好的解決辦法是CGI wrap程序。CGI Wrap,可以在using CGI Web站點中找到,是一個簡單的包裝,它以擁有該文件的用戶而不是服務器指定的用戶來運行CGI腳本。這種簡單的預防措施使腳本擁有者對它可能的危害負責。
因為CGI wrap使得CGI腳本的作者負責他們自己的腳本權限,所以它不僅是一個保護其他人擁有的重要文件的有力的工具,而且是促使人們編寫安全的腳本的有力的工具。只有他們自己的文件會處于危險之中,這樣的現(xiàn)實對腳本作者會是極大的促進。
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>"
現(xiàn)在,如果腳本上設置的權限允許某個惡意的用戶將程序改變?nèi)缦?
#!/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 本地文件安全
腳本在本地硬盤上創(chuàng)建的文件的完整性也同樣重要。在得到Web用戶輸入的一個合理的文件名之后,使用該文件名干什么也很重要。根據(jù)Web服務器運行的操作系統(tǒng),權限和擁有者信息可以與文件中的數(shù)據(jù)一起存在文件上。
例如,UNIX系統(tǒng)能記錄文件訪問權限,包括創(chuàng)建該文件的用戶的權限、同組用戶的權限、以及系統(tǒng)其他人的權限。windows NT使用的是一個更復雜訪問控制清單系統(tǒng),但完成的功能大致相同。根據(jù)這些標志如設置以及授予或禁止什么權限,Web服務器機器的用戶也可能引起麻煩。
例如,在創(chuàng)建一個文件時就應知道給它設置的權限。大部分Web服務器軟件將umask或權限碼設為0000,意味著可以創(chuàng)建一個任何人可讀寫的文件。盡管文件上的權限設置對在Web上瀏覽的人可能沒什么不同,但本地訪問的用戶卻能利用不嚴格的權限設置造成危害;谶@種現(xiàn)實,應該盡可能嚴格地限制文件權限。
保證每個打開文件的調(diào)用都有一個最小限制集合的最簡單的辦法是設置腳本的umask。umask()是一個UNIX調(diào)用,它能對每個后續(xù)的文件創(chuàng)建限制權限。umask()的參數(shù)是一個數(shù)字,用于對后續(xù)的文件創(chuàng)建的權限碼進行屏蔽。如果umask為0022,則不管在打開文件時給組用戶和其他用戶賦予了什么顯式的權限,都將導致創(chuàng)建的文件僅能被用戶自己寫。即使已經(jīng)設置了umask,創(chuàng)建文件時也應該顯式指定權限。如果只有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服務器運行,所以腳本本身的權限設置可以非常嚴格,可以防止任何有企圖的本地用戶修改它。如果對該腳本所在的目錄也設置了正確的權限的話,看起來就沒什么地方可以出問題了,是不是?
當然還有問題。記住得要有點偏激。
上述程序清單調(diào)用了外部程序,在本例中是echo和fortune。因為這些腳本沒有用顯式路徑指明它們在硬盤上的位置,該shell即使用PATH環(huán)境變量來找到它們,從變量中的每一項查找要執(zhí)行的程序。這可能很危險。例如,如果fortune程序安裝在/usr/games中,但PATH中在它之前列出了/TMP,那么任何碰巧命名為"fortune"并位于臨時目錄的程序都會被執(zhí)行,而不是真正的fortune。
該程序可以做它的創(chuàng)建者想做的任何事情,可以刪除文件,也可以登記有關請求信息并將數(shù)據(jù)傳給真正的fortune——使用戶和編程者誰也不聰明。在CGI腳本中運行外部程序時一定要指定顯式的路徑。PATH環(huán)境變量有很大作用,但它與其他變量一樣也能被非法使用。