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

PHP eval() 函數風險與禁用方案:語言結構無法由 disable_functions 禁止

     編輯:PHP 相關知識

核心事實:eval() 不是函數,是語言結構

eval() 在 PHP 內核中被實作為語言結構,而非標準函數。因此 php.ini 的 disable_functions 指令完全無法禁用 eval(),這是許多開發者的常見誤區。

eval() 的極高風險

<?php
// 極度危險:直接執行使用者輸入的程式碼
eval($_POST['cmd']);

// 看似無害但同樣危險:動態拼接程式碼
$action = $_GET['action'];
eval("$action();"); // 攻擊者可傳入 "system('rm -rf /');"

一旦攻擊者控制傳入 eval() 的字串,即可獲得與 PHP 進程相同權限的任意程式碼執行能力(RCE)。

現代 PHP 禁用 eval() 的可行方案

方案一:uopz 擴展(PHP 7.1+,推薦)

uopz 是 PECL 擴展,可在運行時修改/禁用語言結構:

<?php
// 在應用程式啟動早期(如 bootstrap.php)呼叫
if (extension_loaded('uopz')) {
    uopz_set_return('eval', null, true); // 讓 eval() 永遠回傳 null 並拋出錯誤
    // 或完全取消定義
    // uopz_undefine('eval');
}

安裝:pecl install uopz,並在 php.ini 載入 extension=uopz。

方案二:Suhosin 擴展(僅適用 PHP 5.x,已停止維護)

舊文獻常提及 Suhosin 的 suhosin.executor.disable_eval = On,但 Suhosin 專案自 2017 年起停止維護,不支援 PHP 7+,**不建議新專案採用**。

方案三:靜態分析與 CI 攔截

在部署流程中整合靜態分析工具,禁止 eval() 出現在代碼庫:

方案四:架構層面杜絕動態程式碼執行

  1. 拒絕所有 eval() 使用場景:動態配置改用 JSON/YAML + 解析器;插件系統改用介面/抽象類別 + 依賴注入;模板引擎改用 Twig/Blade 等沙箱化引擎。
  2. 代碼審查強制規則:PR 模板加入「確認無 eval/assert/create_function/preg_replace /e 等動態執行」檢查項。
  3. 運行時監控:搭配 Inspector 或 RASP 方案監控可疑函數呼叫。

相關危險結構同樣需注意

結構/函數風險替代方案
assert()PHP 7 前可執行字串程式碼改用 assert(true === $condition) 嚴格模式
create_function()內部使用 eval(),PHP 7.2 棄用,8.0 移除匿名函數 fn() => ...
preg_replace() /e修飾符執行替換結果為程式碼,PHP 7.0 移除preg_replace_callback()
call_user_func() 配合動態字串間接動態呼叫白名單驗證後呼叫

結語

eval() 無法透過 php.ini 禁用,必須採用 uopz 擴展(運行時)、靜態分析(構建時)與架構規範(設計時)三層防禦。現代 PHP 開發應堅持「拒絕動態程式碼執行」原則,從源頭消除 RCE 攻擊面。

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