PHP 8.4.13受CVE-2026-109618/CVE-2026-109619“php2shell”漏洞影响,该漏洞为未经认证的远程代码执行漏洞,源于OOM处理缺陷与全局状态残留导致的释放后使用,需升级至8.4.27或采取禁用eval/unserialize、改用proc_open、部署RASP等应用层加固措施。

PHP 8.4.13 本身不包含已知的命令执行漏洞,但你真正要防范的,是 2026年10月21日发布的 PHP 8.4.27 所修复的 CVE-2026-109618 / CVE-2026-109619(“PHP2Shell”)远程代码执行漏洞。该漏洞影响所有低于 8.4.27 的 8.4.x 版本,包括 8.4.13 —— 它属于 PHP 解析器底层的内存管理缺陷,可被构造的恶意 PHP 字节码或特定 unserialize 流触发,导致未经认证的远程代码执行。
CI 框架(如 CodeIgniter 3/4)本身不修复 PHP 内核漏洞,但其代码结构和使用习惯会显著放大或缓解风险。安全改造的核心不是“给 CI 加补丁”,而是在 CI 应用层切断攻击链路、限制利用条件、提升检测能力。以下是关键改造方向:
明确禁用高危语言构造与反序列化入口
PHP 8.4.13 环境下,eval()、assert()、unserialize() 是最常被“PHP2Shell”漏洞利用的跳板。CI 框架中这些调用往往藏在非显眼位置:
-
CI_Loader::_ci_load_library()中动态加载类名拼接 - 自定义钩子(Hooks)或第三方插件里用
eval()解析配置字符串 - 日志模块、缓存驱动(如 APCu、Redis)中对用户可控数据的反序列化
建议操作:
立即学习“PHP免费学习笔记(深入)”;
- 在
application/config/config.php中设置'log_threshold' => 0(禁用日志)或确保日志内容不写入 PHP 可执行路径(如/var/www/html/logs/) - 全局搜索项目中
eval(、assert(、unserialize(,全部替换为白名单校验 +json_decode()或igbinary_unserialize()(需开启扩展) - 若必须用
unserialize(),强制指定allowed_classes => [](PHP 8.4+ 默认行为),并配合__wakeup()中添加throw new Exception('Forbidden')
利用 PHP 8.4 新特性加固对象边界
PHP 8.4 的属性钩子(Property Hooks) 和非对称可见性(Asymmetric Visibility) 可主动拦截危险赋值,替代传统魔术方法,避免 __set() 被绕过:
// ✅ 推荐:用属性钩子封装输入处理
class SafeInputHandler {
public string $ip;
public function __construct() {
// 钩子只允许合法 IP 格式赋值,拒绝分号、管道符等 shell 元字符
$this->ip = '';
}
public function ip(): string {
return $this->ip;
}
public function ip(string $value): void {
if (!filter_var($value, FILTER_VALIDATE_IP)) {
throw new InvalidArgumentException('Invalid IP format');
}
$this->ip = $value;
}
}建议操作:
立即学习“PHP免费学习笔记(深入)”;
- 将 CI 的
$_GET/$_POST参数统一注入到带钩子的 DTO 类中,而非直接拼接进shell_exec("ping {$ip}") - 对控制器中所有接收用户输入的属性,声明为
public readonly string $xxx;或配合钩子做预处理 - 禁用
__call()和__invoke()动态调用,防止攻击者通过反射触发隐藏逻辑
重写系统命令调用方式,杜绝拼接
CI 中常见 exec("convert -resize {$width}x{$height} {$input} {$output}") 类代码,这是命令注入温床。PHP 8.4 提供更安全的替代方案:
建议操作:
立即学习“PHP免费学习笔记(深入)”;
- 使用
proc_open()替代exec()/shell_exec(),严格控制 stdin/stdout/stderr,并传入参数数组(非字符串拼接):$descriptors = [ 0 => ['pipe', 'r'], // stdin 1 => ['pipe', 'w'], // stdout 2 => ['pipe', 'w'] // stderr ]; $process = proc_open('convert', [['pipe', 'r'], ['pipe', 'w'], ['pipe', 'w']], $pipes); if (is_resource($process)) { fwrite($pipes[0], file_get_contents($input)); // 二进制安全传参 fclose($pipes[0]); $output = stream_get_contents($pipes[1]); fclose($pipes[1]); proc_close($process); } - 对
ping、curl、wget等网络诊断命令,改用 CI 内置的cURL类或GuzzleHttp\Client,完全脱离 shell - 删除所有
system()、passthru()、反引号`...`用法,CI 3.x 中exec()默认启用需在php.ini中设为disable_functions = exec,system,passthru,shell_exec,proc_open,popen
部署运行时防护层(RASP)作为兜底
即使代码层加固,仍需防御 0day 利用。PHP 8.4.13 环境可部署轻量 RASP:
- 启用宝塔内置「PHP 安全防护」模块(支持 8.4),开启「禁止 eval 执行」、「拦截危险函数调用」、「WebShell 特征扫描」
- 或手动安装
PHP_diseval_extension(专为 8.4 编译),彻底拦截eval()调用:cd /PHP_diseval_extension/source /www/server/php/84/bin/phpize ./configure --with-php-config=/www/server/php/84/bin/php-config make && make install echo "extension=php_diseval.so" >> /www/server/php/84/etc/php.ini service php-fpm-84 restart
- 配合 Nginx 的
mod_security规则,拦截含;、|、&&、$()的请求 URI 和 POST body
不复杂但容易忽略



















