- 論壇徽章:
- 0
|
PHP 安全 (1)
原作:John Coggeshall 07/31/2003
原文:http://www.onlamp.com/pub/a/php/2003/07/31/php_foundations.html
在最近的兩篇專欄文章(《常見樣式錯誤(上)》和《常見樣式錯誤(下)》)中我討論了一些在編寫PHP程式時常見的使程式難于閱讀和易導致BUG的壞習慣。
在今天的文章中,我將轉向討論這個系列的重點:使用PHP時,安全問題的重要性。
關注安全問題的重要性
看到的遠非全部
阻止用戶惡意破壞你的程式最有效卻經(jīng)常被忽略的方法是在寫代碼時就考慮它的可能性。留意代碼中可能的安全問題是很重要的?紤]下邊的旨在簡化用PHP中寫入大量文本文件的過程的實例函數(shù):
?php
function write_text($filename, $text="") {
static $open_files = array();
// 如果文件名空,關閉全部文件
if ($filename == NULL) {
foreach($open_files as $fr) {
fclose($fr);
}
return true;
}
$index = md5($filename);
if(!isset($open_files[$index])) {
$open_files[$index] = fopen($filename, "a+");
if(!$open_files[$index]) return false;
}
fputs($open_files[$index], $text);
return true;
}?>
這個函數(shù)帶有兩個缺省參數(shù),文件名和要寫入文件的文本。
函數(shù)將先檢查文件是否已被打開;如果是,將使用原來的文件句柄。否則,將自行創(chuàng)建。在這兩種情況中,文本都會被寫入文件。
如果傳遞給函數(shù)的文件名是NULL,那么所有打開的文件將被關閉。下邊提供了一個使用上的實例。
如果開發(fā)者以下邊的格式來寫入多個文本文件,那么這個函數(shù)將清楚和易讀的多。
讓我們假定這個函數(shù)存在于一個單獨的文件中,這個文件包含了調(diào)用這個函數(shù)的代碼。
下邊是一個這樣的程式,我們叫它quotes.php:
html>body>
form action="" method="get">
Choose the nature of the quote:
select name="quote" size="3">
option value="funny">Humorous quotes/option>
option value="political">Political quotes/option>
option value="love">Romantic Quotes/option>
/select>br />
The quote: input type="text" name="quote_text" size="30" />
input type="submit" value="Save Quote" />
/form>
/body>/html>
?php
include_once('write_text.php');
$filename = "/home/web/quotes/{$_GET['quote']}";
$quote_msg = $_GET['quote_text'];
if (write_text($filename, $quote_msg)) {
echo "Quote saved!";
} else {
echo "Error writing quote";
}
write_text(NULL);
?>
如同你看到的,這位開發(fā)者使用了write_text()函數(shù)來創(chuàng)建一個體系使得用戶可以提交他們喜歡的格言,這些格言將被存放在一個文本文件中。
不幸的是,開發(fā)者可能沒有想到,這個程式也允許了惡意用戶危害web server的安全。
也許現(xiàn)在你正撓著頭想著究竟這個看起來很無辜的程式怎樣引入了安全風險。
如果你看不出來,考慮下邊這個URL,記住這個程式叫做quotes.php:
http://www.somewhere.com/fun/quotes.php?quote=different_file.dat"e_text=garbage+data
當這個URL傳遞給web server 時將會發(fā)生什么?
顯然,quotes.php將被執(zhí)行,但是,不是將一句格言寫入到我們希望的三個文件中之一,相反的,一個叫做different_file.dat的新文件將被建立,其中包含一個字符串garbage data。
顯然,這不是我們希望的行為,惡意用戶可能通過把quote指定為../../../etc/passwd來訪問UNIX密碼文件從而創(chuàng)建一個帳號(盡管這需要web server以superuser運行程式,如果是這樣的,你應該停止閱讀,馬上去修復它)。
如果/home/web/quotes/可以通過瀏覽器訪問,可能這個程式最嚴重的安全問題是它允許任何用戶寫入和運行任意PHP程式。這將帶來無窮的麻煩。
這里有一些解決方案。如果你只需要寫入目錄下的一些文件,可以考慮使用一個相關的數(shù)組來存放文件名。如果用戶輸入的文件存在于這個數(shù)組中,就可以安全的寫入。另一個想法是去掉所有的不是數(shù)字和字母的字符來確保沒有目錄分割符號。還有一個辦法是檢查文件的擴展名來保證文件不會被web server執(zhí)行。
原則很簡單,作為一個開發(fā)者你必須比程式在你希望的情況下運行時考慮更多。
如果非法數(shù)據(jù)進入到一個form元素中會發(fā)生什么?惡意用戶是否能使你的程式以不希望的方式運行?什么方法能阻止這些攻擊?你的web server和PHP程式只有在最弱的安全鏈接下才安全,所以確認這些可能不安全的鏈接是否安全很重要。
常見的涉及安全的錯誤
這里給出一些要點,一個可能危及安全的編碼上的和管理上的失誤的簡要不完整列表
錯誤1。信賴數(shù)據(jù)
這是貫穿于我關于PHP程式安全的討論的主題,你決不能相信一個來自外部的數(shù)據(jù)。不管它來自用戶提交表單,文件系統(tǒng)的文件或者環(huán)境變量,任何數(shù)據(jù)都不能簡單的想當然的采用。所以用戶輸入必須進行驗證并將之格式化以保證安全。
錯誤2。在web目錄中存儲敏感數(shù)據(jù)
任何和所有的敏感數(shù)據(jù)都應該存放在獨立于需要使用數(shù)據(jù)的程式的文件中,并保存在一個不能通過瀏覽器訪問的目錄下。當需要使用敏感數(shù)據(jù)時,再通過include 或 require語句來包含到適當?shù)腜HP程式中。
錯誤3。不使用推薦的安全防范措施
PHP手冊包含了在使用和編寫PHP程式時關于安全防范的完整章節(jié)。手冊也(幾乎)基于案例清楚的說明了什么時候存在潛在安全風險和怎么將風險降低到最低。又如,惡意用戶依靠開發(fā)者和管理員的失誤得到關心的安全信息以獲取系統(tǒng)的權限。留意這些警告并適當?shù)牟扇〈胧﹣頊p小惡意用戶給你的系統(tǒng)帶來真正的破壞的可能性。
![]()
本文來自ChinaUnix博客,如果查看原文請點:http://blog.chinaunix.net/u3/93245/showart_1895862.html |
|