給使用 OpenBSD 和 PHP 的使用者:預設的 php.ini 設定為 display_errors=off,這與 PHP 預設的 display_errors=on 相反。如果您在 OpenBSD 上看不到錯誤訊息,請務必編輯您的 php.ini 將 display_errors 設定為 on。(我在 OpenBSD 4.4 上遇到過這個問題)
就 PHP 安全性而言,錯誤回報有兩個面向。一個有利於提高安全性,另一個則有害。
一種標準的攻擊策略是透過提供不正確的資料來分析系統,並檢查返回的錯誤類型和上下文。這讓系統駭客可以探測伺服器的資訊,以確定可能的弱點。例如,如果攻擊者根據先前提交的表單收集了有關頁面的資訊,他們可能會嘗試覆寫變數或修改它們
範例 #1 使用自訂 HTML 頁面攻擊變數
<form method="post" action="attacktarget?username=badfoo&password=badfoo"> <input type="hidden" name="username" value="badfoo" /> <input type="hidden" name="password" value="badfoo" /> </form>
PHP 回傳的錯誤訊息通常對試圖除錯腳本的開發人員很有幫助,這些訊息會指出例如失敗的函式或檔案、發生錯誤的 PHP 檔案,以及錯誤發生的行號。這些資訊都可能被利用。PHP 開發人員使用 show_source()、highlight_string() 或 highlight_file() 作為除錯手段並不少見,但在正式網站上,這可能會暴露隱藏的變數、未檢查的語法和其他危險資訊。尤其危險的是,從已知來源執行具有內建除錯處理程式的程式碼,或使用常見的除錯技巧。如果攻擊者可以判斷您使用的是哪種通用技巧,他們可能會嘗試透過發送各種常見的除錯字串來暴力破解頁面。
範例 #2 利用常見的除錯變數
<form method="post" action="attacktarget?errors=Y&showerrors=1&debug=1"> <input type="hidden" name="errors" value="Y" /> <input type="hidden" name="showerrors" value="1" /> <input type="hidden" name="debug" value="1" /> </form>
無論錯誤處理方法為何,探測系統錯誤的能力都會讓攻擊者獲得更多資訊。
例如,一般 PHP 錯誤的樣式本身就表明系統正在運行 PHP。如果攻擊者正在查看 .html
頁面,並且想要探測後端(以尋找系統中的已知弱點),則透過提供錯誤的資料,他們或許可以判斷系統是用 PHP 建構的。
函式錯誤可以指出系統是否可能正在運行特定的資料庫引擎,或者提供網頁程式設計或設計方式的線索。這允許對開放的資料庫埠進行更深入的調查,或尋找網頁中的特定錯誤或弱點。例如,透過提供不同的錯誤資料片段,攻擊者可以判斷腳本中驗證的順序(從行號錯誤中),以及探測腳本中不同位置可能被利用的漏洞。
檔案系統或一般 PHP 錯誤可以指出網頁伺服器具有的權限,以及網頁伺服器上檔案的結構和組織。開發人員編寫的錯誤程式碼可能會加劇這個問題,導致先前「隱藏」的資訊容易被利用。
這個問題主要有三種解決方案。第一種是仔細檢查所有函式,並嘗試彌補大部分的錯誤。第二種是在正在執行的程式碼上完全停用錯誤報告。第三種是使用 PHP 的自訂錯誤處理函式來建立您自己的錯誤處理程式。根據您的安全策略,您可能會發現這三種方法都適用於您的情況。
提前發現這個問題的方法之一是利用 PHP 自身的 error_reporting() 函式,來幫助您保護程式碼並找出可能很危險的變數使用方式。透過在部署之前使用 E_ALL
測試您的程式碼,您可以快速找到變數可能被污染或以其他方式修改的區域。一旦您準備好部署,您應該透過將 error_reporting() 設定為 0 來完全停用錯誤報告,或者使用 php.ini 選項 display_errors
關閉錯誤顯示,以保護您的程式碼免受探測。如果您選擇後者,您還應該使用 error_log
ini 指令設定日誌檔案的路徑,並開啟 log_errors
。
範例 #3 使用 E_ALL 尋找危險變數
<?php
if ($username) { // 未初始化或在使用前未經檢查
$good_login = 1;
}
if ($good_login == 1) { // 如果上述測試失敗,則未初始化或在使用前未經檢查
readfile ("/highly/sensitive/data/index.html");
}
?>
給使用 OpenBSD 和 PHP 的使用者:預設的 php.ini 設定為 display_errors=off,這與 PHP 預設的 display_errors=on 相反。如果您在 OpenBSD 上看不到錯誤訊息,請務必編輯您的 php.ini 將 display_errors 設定為 on。(我在 OpenBSD 4.4 上遇到過這個問題)