2026年10月21日,PHP 发布紧急安全更新,修复被称为 php2shell 的两个严重远程代码执行漏洞:CVE-2026-109618 和 CVE-2026-109619,两者的 CVSS v4.0 评分均为 9.2。

对站长来说,先做两件事:找到实际处理网站请求的 PHP,安装对应安全补丁并替换旧工作进程。只更新 CMS、看一次 php -v,或在配置里关闭一个功能,都不足以完成整改。

本文依据截至 2026年10月22日 的公开资料整理,说明排查与修复方法;不包含攻击载荷,也未对本站或用户服务器进行漏洞利用和生产升级。漏洞评分与编号可见 PHP 官方安全通告及另一份通告。

先核对修复版本

本次上游修复版本如下。表中的“之前”针对各自分支,不能把不同分支的版本号混在一起比较。

PHP 分支 该分支需更新的上游版本 首个修复版本
8.2 8.2.35 之前 8.2.35
8.3 8.3.36 之前 8.3.36
8.4 8.4.27 之前 8.4.27
8.5 8.5.12 之前 8.5.12

PHP 官方公告要求所有通过 PHP 处理 Web 请求的部署及时更新,范围包括 PHP-FPM、Apache mod_php、php-cgi、FrankenPHP 和 LiteSpeed。不能因为使用 Nginx + FPM,就直接排除风险。

PHP 8.1 及更老分支不再获得 PHP 项目的常规版本更新。官方此次额外提供了7.4、8.0、8.1的最小源码回移补丁,发行版也可能提供自己的维护包;这不意味着旧分支恢复了长期上游支持。已有可用修复包时先修补,再制定迁移计划。

两个漏洞分别发生在哪里?

CVE-2026-109618:内存不足后的清理碰到未完成状态

PHP 处理请求时需要分配内存。如果分配失败发生在内部结构尚未完整初始化的时刻,异常退出可能留下无效状态,随后请求清理又使用它。

官方确认 Apache mod_php 存在经 HTTP 验证的未认证 RCE 路径,可在应用代码执行前触发。FPM 对启动失败的处理不同,但其他阶段仍可能受影响;官方通告中的“尚未演示完整 FPM 利用”不能改写成“FPM 已确认安全”。OOM 漏洞通告

CVE-2026-109619:旧请求释放了内存,worker 还留着引用

一个 worker 可以连续处理多个请求。如果某个请求的内存已经释放,内部全局状态却仍指向那里,下一个由同一 worker 处理的请求可能使用失效引用,形成 use-after-free。

它涉及状态产生、清理和后续读取的组合。会话上传进度是已确认的一类读取入口,但并非唯一入口;不同 SAPI、配置与扩展会改变具体条件。跨请求状态漏洞通告

因此,无需身份验证,不等于所有部署都能被同一请求无条件攻破。但也不能反过来,以某个演示没覆盖自己的组合为理由推迟补丁。

php2shell两个漏洞分别涉及OOM后无效状态与跨请求失效引用

图为请求生命周期的简化示意,不表示所有SAPI具有相同的利用路径。

为什么网站有登录、没有上传入口,仍然要查?

PHP 的请求解析和运行时初始化,不完全发生在业务代码之后。若问题先于应用执行,登录校验、框架中间件和业务权限判断就没有机会先拦住它。

没有“上传页面”也不能证明 PHP 不解析相应请求。是否能够到达运行时,取决于前端和服务器实际处理路径,而不是页面上有没有文件选择按钮。PHP 请求解析与风险说明

对于所谓“全面接管”,还应区分权限:经验证的影响是以 Web worker 账号执行代码。它可能危及该账号能读取的配置、数据库凭据和能写入的网站文件;能否进一步取得主机 root 权限,还取决于额外漏洞、权限配置与隔离边界。不要把 RCE 自动写成已经实现 root 提权。官方影响说明

排查第一步:找到真正对外的 PHP

一台服务器可能同时存在系统 PHP、面板安装的 PHP、多个 FPM 池,以及容器内的 PHP。每套环境都需要归属到具体站点。

可以先在 Linux shell 中收集线索:

1
2
3
4
command -v php
php -v
php --ini
ps -eo pid,lstart,args | grep -E '[p]hp-fpm|[a]pache2|[h]ttpd'

这些命令看到的 CLI 版本和配置,不代表网站使用的版本和配置。继续检查站点的 FastCGI socket、FPM 服务或容器映射,建立下面这张清单:

记录项 需要确认的内容
站点与入口 域名、代理、后端及是否能绕过代理直连
运行时 PHP 分支、SAPI、实际可执行文件或模块
来源 发行版包、面板、自编译程序或容器镜像
配置 实际加载的配置、FPM池及站点覆盖项
修复状态 安全公告、完整包版本或镜像摘要
进程 何时替换旧worker,如何验证新请求

必要时,可在仅管理员可访问的临时诊断路径中返回最小信息:

1
2
3
4
5
6
<?php
header('Content-Type: application/json; charset=utf-8');
echo json_encode([
'version' => PHP_VERSION,
'sapi' => PHP_SAPI,
]);

通过真实 Web 路径访问,再与配置、包记录交叉核对。检查完成后删除该路径;不要长期公开 phpinfo() 页面。此方法只辅助识别运行时,不是漏洞扫描或“未被入侵”的证明。

排查第二步:正确理解发行版的补丁回移

上游修复版本表不能直接替代发行版安全通知。发行版可能保留较旧的上游版本前缀,把修复回移到自己的包修订中。

例如,Ubuntu USN-8948-1列出的修复包包括:

Ubuntu 版本 对应修复包版本
22.04 LTS 8.1.2-1ubuntu2.28
24.04 LTS 8.3.6-0ubuntu0.24.04.13
26.04 LTS 8.5.4-0ubuntu1.5
26.10 8.5.9-0ubuntu2.1

这张表只适用于该 Ubuntu 公告和对应包来源。不能拿它判断第三方 PPA、面板或自行编译的同名版本。

以 Ubuntu 24.04 的 FPM 部署为例,先核对已安装包和候选包:

1
2
dpkg-query -W 'php8.3*'
apt-cache policy php8.3-fpm php8.3-cli

同时确认软件源来自哪里,候选版本是否已包含修复。Ubuntu 官方另有此次更新说明,旧发行版的修复可能需要相应 ESM 支持。

修复第三步:升级,再替换旧工作进程

发行版包:更新实际安装的组件

先完成配置和业务数据备份,确认包来源、扩展兼容性及恢复方式,再按发行版公告升级。下面仅是 Ubuntu 24.04 已使用 PHP 8.3 FPM 和 CLI 的示例,不适用于所有主机:

1
2
3
4
5
sudo apt update
sudo apt install --only-upgrade php8.3-fpm php8.3-cli
sudo php-fpm8.3 -tt
sudo systemctl restart php8.3-fpm
sudo systemctl --no-pager --full status php8.3-fpm

还应核对实际安装的 common、扩展包及依赖是否同步更新。Apache mod_php 需要更新对应模块并替换加载该模块的 Apache 进程;仅重启 Nginx 不会替换 FPM。服务名称按实际部署填写。

Ubuntu 明确提醒:包升级后,使用 PHP 的应用通常还需要重启。不要把包管理器成功退出当成全部运行中进程已经完成更新。Ubuntu 修复说明

容器与面板:更新网站实际使用的那套运行时

容器场景先核对镜像来源和发布方的修复信息,再更新基础镜像或依赖包,构建或拉取包含补丁的镜像并重建服务。重启旧容器会继续使用旧文件系统;只更新宿主机 PHP 也不会自动修改镜像中的解释器。

记录新镜像摘要、容器启动时间和 Web 检查结果。若存在多个副本,应确认每个副本都已替换,避免部分请求继续落到旧环境。

面板部署同样要逐站核对绑定的 PHP。面板显示“安装了新版本”,不等于站点已切换,也不等于原 FPM 池已经退出。

从定位实际PHP运行时到核对补丁、替换进程及业务验收的流程

确认新请求实际使用更新后的运行时,而不只检查安装目录。

暂时不能升级,哪些措施只能争取时间?

完整修复依赖补丁。 临时配置只能减少部分路径的暴露,不能作为长期替代。

常见做法 应如何理解
关闭 session.upload_progress.enabled 只能阻断已确认的部分会话路径,不能覆盖两个漏洞的所有变体
在业务代码里调用 ini_set() 对早于应用代码的解析或初始化来得太晚
降低请求体大小、过滤不需要的 multipart 可缩小暴露面,但不能证明所有内存消耗路径均被阻断
隐藏 PHP 错误输出 隐藏提示不等于消除内部状态读取
启用 WAF 作为纵深防护,不能替代运行时更新

其中,PHP 的上传进度文档说明,相关会话信息在脚本执行前就会写入;状态漏洞通告也明确指出,抑制错误显示不能消除相应风险。

另一个容易误用的选项是 memory_limit=-1。它可减少受控 PHP 内存上限触发的部分 OOM 路径,但底层分配失败仍可能到达漏洞代码,而且取消限制会带来资源耗尽风险。不能照抄后宣布安全,也不能随意用地址空间限制代替,后者可能恰好制造分配失败。OOM 通告的缓解边界

如果短时间无法确认修复,可以先限制暴露入口或暂停受影响服务,再安排补丁和恢复验证。前端限制应覆盖实际可达路径,不能只保护某个页面、某个域名或一条上传路由。

升级完成后,怎样验收?

至少保留以下结果:

  1. 版本证据:上游修复版本,或发行版公告对应的完整包版本。
  2. 进程证据:旧worker已退出,新请求由更新后的进程或容器处理。
  3. 业务证据:首页、登录、表单、上传及后台等关键路径正常。
  4. 配置证据:临时诊断页面已移除,临时限制有明确保留或撤销计划。
  5. 排查记录:异常请求、错误日志、子进程和文件变化是否需要进一步调查。

内存不足、worker退出或异常大表单,单独出现都不能证明攻击成功;没有这些日志,也不能证明从未被利用。如果发现 PHP 进程启动异常命令、出现未知脚本或配置被修改,应保留证据并进入事件处置,而不是打完补丁就结束。

此次整改的终点,是实际对外服务已经使用含修复的 PHP,旧进程已被替换,并完成业务与异常核查。仅有一张 CLI 版本截图,无法说明所有站点、容器和副本都已修复。