php2shell:PHP 两个 9.2 分 RCE 漏洞,站长如何排查与修复?
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、配置与扩展会改变具体条件。跨请求状态漏洞通告
因此,无需身份验证,不等于所有部署都能被同一请求无条件攻破。但也不能反过来,以某个演示没覆盖自己的组合为理由推迟补丁。

图为请求生命周期的简化示意,不表示所有SAPI具有相同的利用路径。
为什么网站有登录、没有上传入口,仍然要查?
PHP 的请求解析和运行时初始化,不完全发生在业务代码之后。若问题先于应用执行,登录校验、框架中间件和业务权限判断就没有机会先拦住它。
没有“上传页面”也不能证明 PHP 不解析相应请求。是否能够到达运行时,取决于前端和服务器实际处理路径,而不是页面上有没有文件选择按钮。PHP 请求解析与风险说明
对于所谓“全面接管”,还应区分权限:经验证的影响是以 Web worker 账号执行代码。它可能危及该账号能读取的配置、数据库凭据和能写入的网站文件;能否进一步取得主机 root 权限,还取决于额外漏洞、权限配置与隔离边界。不要把 RCE 自动写成已经实现 root 提权。官方影响说明
排查第一步:找到真正对外的 PHP
一台服务器可能同时存在系统 PHP、面板安装的 PHP、多个 FPM 池,以及容器内的 PHP。每套环境都需要归属到具体站点。
可以先在 Linux shell 中收集线索:
1 | command -v php |
这些命令看到的 CLI 版本和配置,不代表网站使用的版本和配置。继续检查站点的 FastCGI socket、FPM 服务或容器映射,建立下面这张清单:
| 记录项 | 需要确认的内容 |
|---|---|
| 站点与入口 | 域名、代理、后端及是否能绕过代理直连 |
| 运行时 | PHP 分支、SAPI、实际可执行文件或模块 |
| 来源 | 发行版包、面板、自编译程序或容器镜像 |
| 配置 | 实际加载的配置、FPM池及站点覆盖项 |
| 修复状态 | 安全公告、完整包版本或镜像摘要 |
| 进程 | 何时替换旧worker,如何验证新请求 |
必要时,可在仅管理员可访问的临时诊断路径中返回最小信息:
1 |
|
通过真实 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 | dpkg-query -W 'php8.3*' |
同时确认软件源来自哪里,候选版本是否已包含修复。Ubuntu 官方另有此次更新说明,旧发行版的修复可能需要相应 ESM 支持。
修复第三步:升级,再替换旧工作进程
发行版包:更新实际安装的组件
先完成配置和业务数据备份,确认包来源、扩展兼容性及恢复方式,再按发行版公告升级。下面仅是 Ubuntu 24.04 已使用 PHP 8.3 FPM 和 CLI 的示例,不适用于所有主机:
1 | sudo apt update |
还应核对实际安装的 common、扩展包及依赖是否同步更新。Apache mod_php 需要更新对应模块并替换加载该模块的 Apache 进程;仅重启 Nginx 不会替换 FPM。服务名称按实际部署填写。
Ubuntu 明确提醒:包升级后,使用 PHP 的应用通常还需要重启。不要把包管理器成功退出当成全部运行中进程已经完成更新。Ubuntu 修复说明
容器与面板:更新网站实际使用的那套运行时
容器场景先核对镜像来源和发布方的修复信息,再更新基础镜像或依赖包,构建或拉取包含补丁的镜像并重建服务。重启旧容器会继续使用旧文件系统;只更新宿主机 PHP 也不会自动修改镜像中的解释器。
记录新镜像摘要、容器启动时间和 Web 检查结果。若存在多个副本,应确认每个副本都已替换,避免部分请求继续落到旧环境。
面板部署同样要逐站核对绑定的 PHP。面板显示“安装了新版本”,不等于站点已切换,也不等于原 FPM 池已经退出。

确认新请求实际使用更新后的运行时,而不只检查安装目录。
暂时不能升级,哪些措施只能争取时间?
完整修复依赖补丁。 临时配置只能减少部分路径的暴露,不能作为长期替代。
| 常见做法 | 应如何理解 |
|---|---|
关闭 session.upload_progress.enabled |
只能阻断已确认的部分会话路径,不能覆盖两个漏洞的所有变体 |
在业务代码里调用 ini_set() |
对早于应用代码的解析或初始化来得太晚 |
| 降低请求体大小、过滤不需要的 multipart | 可缩小暴露面,但不能证明所有内存消耗路径均被阻断 |
| 隐藏 PHP 错误输出 | 隐藏提示不等于消除内部状态读取 |
| 启用 WAF | 作为纵深防护,不能替代运行时更新 |
其中,PHP 的上传进度文档说明,相关会话信息在脚本执行前就会写入;状态漏洞通告也明确指出,抑制错误显示不能消除相应风险。
另一个容易误用的选项是 memory_limit=-1。它可减少受控 PHP 内存上限触发的部分 OOM 路径,但底层分配失败仍可能到达漏洞代码,而且取消限制会带来资源耗尽风险。不能照抄后宣布安全,也不能随意用地址空间限制代替,后者可能恰好制造分配失败。OOM 通告的缓解边界
如果短时间无法确认修复,可以先限制暴露入口或暂停受影响服务,再安排补丁和恢复验证。前端限制应覆盖实际可达路径,不能只保护某个页面、某个域名或一条上传路由。
升级完成后,怎样验收?
至少保留以下结果:
- 版本证据:上游修复版本,或发行版公告对应的完整包版本。
- 进程证据:旧worker已退出,新请求由更新后的进程或容器处理。
- 业务证据:首页、登录、表单、上传及后台等关键路径正常。
- 配置证据:临时诊断页面已移除,临时限制有明确保留或撤销计划。
- 排查记录:异常请求、错误日志、子进程和文件变化是否需要进一步调查。
内存不足、worker退出或异常大表单,单独出现都不能证明攻击成功;没有这些日志,也不能证明从未被利用。如果发现 PHP 进程启动异常命令、出现未知脚本或配置被修改,应保留证据并进入事件处置,而不是打完补丁就结束。
此次整改的终点,是实际对外服务已经使用含修复的 PHP,旧进程已被替换,并完成业务与异常核查。仅有一张 CLI 版本截图,无法说明所有站点、容器和副本都已修复。