專家提醒 Perl腳本中的安全隱患
本文和大家重點討論一下Perl腳本中的一些安全問題,幾乎每一種編程語言都有一定這樣的漏洞,這種漏洞將會在某種程度上導致不安全軟件的產生,Perl也有它安全上令人擔憂的部分,然而大多數程序員完全沒有意識到這些方面。
Perl腳本中的一些安全問題
對一種編程語言而言,在設計這種語言的時候,一般是不會產生安全隱患的,事實上,這種隱患是由程序員引入的。幾乎每一種編程語言都有一定這樣的漏洞,這種漏洞將會在某種程度上導致不安全軟件的產生,但是一個如軟件整體的安全性仍然大部分依賴于這個軟件制造者的知識面、理解能力和他的安全意識。Perl也有它安全上令人擔憂的部分,然而大多數程序員完全沒有意識到這些方面。
在這篇文章里,我們將會看一下Perl中一些最普遍被誤用和忽視的屬性。我們將會看到它們的誤用將會怎樣對運行它們的系統的安全以及它們的用戶造成威脅。我們將會演示怎樣把這些弱點挖掘出來以及如何去修改、避免它們。
用戶輸入上的弱點
Perl腳本中產生安全問題的一個很大的來源是沒有經過正確確認(或根本就沒有確認)的用戶的輸入。每次當你的程序要從一個不信任用戶那里獲取輸入信息的時候,即使采用的是非直接的方式,你都應該小心。舉個例子來說吧,如果你在Perl中寫CGI腳本,你要預期到惡意的用戶將會發送給你假的輸入。不正確的用戶輸入,如果沒有經過確認就被認可并使用了,將會導致許多方面出錯。最常見和明顯的錯誤是,沒有經過確認就去執行有用戶自定義參數的其他程序。
syetem()和exec()函數
Perl腳本以能被用作一種“粘合”語言而著稱——它能夠通過如下方式完成一個出色的工作:在調用其他程序來為它工作的時候,通過采集一個程序的輸出,將它重新格式成一種特定的方式后傳遞到其他程序的輸入的方式仔細的協調它們的運行。這樣各個程序就能很好的運行了。
正如Perl發布標語告許我們的,我們有不止一種方法可以做同樣的事。一種執行一個外部程序和一個系統命令的方法事通過調用exec()函數。當Perl遇到一個exec()語句的時候,它審視exec()被調用處的參數,然后啟動一個新的進程來執行這條特定的命令。Perl腳本從不會返回控制給調用exec()的原來的那個進程。
另一個相似的函數是system()。system()的運行方式非常象exec()。它們之間的唯一的大的區別是Perl會首先從父進程中分叉出一個子進程,子進程作為提供給system()的一個參數。父進程等到子進程結束運行后再接著運行程序的其余部分。我們將會在下面更詳細的討論system()調用,但這些討論大部分也適用于exec()。
傳遞給system()的參數是一個列表——列表里的第一個元素是要被執行的這個程序的程序名,其他元素是傳給這個程序的參數。然而,如果只有一個參數的的話,system()的執行方式會發生差異。在那種情形下,Perl將會掃描這個參數看它是不是包含任何shell轉換字符。如果有的話,它就要把這些字符通過shell來解釋。所以產生一個shell命令行來工作。不然,Perl會降字符串拆成單詞然后調用效率更高的c庫函數execvp(),這個函數不能理解特殊的shell字符。
現在假設我們有一張CGI表單,它要詢問用戶名,然后顯示包含這個用戶統計信息的一個文件。我名可以如下使用system()來調用’cat’實現那種要求:
system("cat/usr/stats/$username");
用戶名來自這樣的一個表單:
$username=param("username");
.舉個例子,當用戶在表單里添上username=jdimov,然后提交后。Perl在字符串``cat/usr/stats/jdimov中沒有找到任何轉換字符創,所以它就調用execvp()函數運行”cat”后返回到我們的腳本中。這個Perl腳本也許看起來沒有害處可言,但是它容易被一個惡意的攻擊者所利用。
【編輯推薦】