Skip to content

PHP 9.2 分漏洞怎么处理:Windows 与 Yaf 项目的排查和升级 ​

完整修复要落在 PHP 运行时;业务代码里的上传校验、登录鉴权和几个配置开关,都不能代替安全补丁。 对依赖旧库和 Windows 扩展的系统,应同时推进应急处置与兼容迁移。

本文从一篇 PHP 漏洞预警出发,结合一个 Windows 部署、使用 Yaf、多应用入口的业务项目做本地静态检查。整理时间为 2026-10-22。案例已脱敏,不公开业务源码、地址、配置或数据。

本次能确认的是源码结构和升级障碍;没有连接生产服务、读取生产日志或运行漏洞利用,也没有执行运行时升级。因此结论是“需要尽快核实并处置”,不能写成“已确认被入侵”或“已经修复”。

先更新新闻时间线,再判断风险 ​

引发排查的微信文章发布于 2026 年 10 月 21 日 13:24,主要内容属于补丁发布前预警。它提出核对实际使用版本、备份和关注异常,这些方向有用;具体补丁状态则需要以随后发布的官方信息为准。

PHP 官方已在 10 月 21 日发布修复,涉及两个 CVSS v4.0 9.2 的漏洞:CVE-2026-109618 和 CVE-2026-109619。这次事件常被称为 PHP2Shell,不能套用其他年份 Windows CGI 漏洞的版本阈值。PHP 官方公告

原文对攻击速度和暴露规模的预测,不作为本文判断项目是否受影响的依据。漏洞存在、部署具备触发条件、攻击已经成功,是三个不同结论。

两个漏洞,不能只关一个开关 ​

漏洞机制概要对排查的提示
CVE-2026-109618内存耗尽中断内部初始化,清理阶段可能处理无效状态不能只检查业务上传函数
CVE-2026-109619请求结束后残留指向已释放内存的状态,后续请求可能使用它需关注持久 worker 与请求前初始化

第一条漏洞的公告明确指出,已验证的 mod_php 路径可以发生在业务代码执行前;第二条的 session 上传进度路径也不以应用主动调用 session_start() 为必要条件。不能因为接口要求登录,或某个页面没使用 Session,就直接排除运行时风险。OOM 公告、残留状态公告

PHP 官方要求核查处理 Web 请求的各种运行方式,包括 PHP-FPM、Apache mod_php、php-cgi、FrankenPHP 和 LiteSpeed。Windows、FastCGI 或反向代理的存在,都不能单独构成“免疫证明”。具体触发条件依赖构建、扩展、配置和应用路径。官方风险范围

仓库检查能证明什么 ​

这次检查的系统由多套 Web 入口和应用目录组成,共享业务库与扩展。与常规“查一行 PHP 版本”相比,有几项更值得注意的事实。

静态发现可以支持的判断不能据此断言
多个入口先启动 Session,再启动 Yaf需要覆盖各入口与其运行时映射Session 调用本身证明漏洞可利用
存在 MVC 上传逻辑及独立 PHP 上传脚本只查主控制器会漏掉执行入口所有脚本都已暴露到公网
未找到应用使用 PHP Session 上传进度的证据关闭该功能可能较少影响业务,值得测试服务器默认功能已经关闭
历史任务注释有 PHP 5.x、7.x 路径存在旧运行时维护历史,需要优先盘点当前 Web 服务必然仍使用这些版本
仓库没有 PHP 二进制、php.ini 和 Web 主配置运行环境需要运维另行核实某个站点使用的具体版本或 SAPI
代码有 PHP 8 移除语法及旧库调用升级必须安排兼容修复这些用法就是本次 RCE 根因

前端上传组件的进度回调,与 PHP 的 session.upload_progress 是不同机制,不能因名称相近而混为一谈。

没有发现上传进度业务代码也不意味着风险消失:PHP 手册说明该功能的处理发生在业务脚本执行前,默认配置会启用它。Session 上传进度、Session 配置

第一步:建立实际运行时清单 ​

应由运维在受控位置盘点“哪个站点、应用池或任务,实际使用哪套 PHP”,而不是只看面板里装了几个版本。

核对项需要记录的事实
站点与入口虚拟主机、绑定目录、独立脚本、受信与公开访问范围
PHP 运行方式Apache 模块、IIS/FastCGI 或其他 SAPI,实际二进制路径
构建身份完整版本、供应商包版本或回补记录、文件校验值
加载配置生效 php.ini、附加 INI、目录覆盖和服务端设置
扩展Yaf、Redis、数据库驱动、图像和加密扩展的构建版本
Windows 匹配项操作系统、x86/x64、TS/NTS、编译工具链与运行库
服务实例所有 worker、应用池、虚拟站点及计划任务是否共用运行时

以下 PowerShell 命令仅供运维盘点指定二进制,路径为虚构示例;它们不会证明 Web 服务实际用了这份 PHP:

powershell
$phpExe = 'C:\runtime\php\php.exe'
& $phpExe -v
& $phpExe --ini
& $phpExe -m

执行后还要对照 Web 服务器的模块或 FastCGI 映射。命令行输出的 SAPI 是 CLI,不能拿它冒充 Web SAPI;装了新 PHP,也不等于服务已切过去。

如果必须通过实际 Web worker 核实,应由运维使用已有的受限诊断通道,只采集版本、SAPI、配置来源和相关配置值,随后清理临时手段。不要在公开目录留一个完整 phpinfo() 页面,也不要把包含连接配置的输出贴到公开文章。

第二步:选择修复路线 ​

截至本文日期,各受支持分支修复这两个漏洞的最低版本如下。实际升级应选该分支包含修复的最新安全版本,并核实下载来源。

当前分支本次最低修复版本
PHP 8.28.2.35
PHP 8.38.3.36
PHP 8.48.4.27
PHP 8.58.5.12

版本阈值按分支判断,不能跨分支直接比较字符串。供应商回补包还需要核对补丁记录,不能只看 php -v 的上游版本部分。官方修复信息

路线适用情况执行重点
同分支补丁升级已在受支持 PHP 分支准备完整运行时与扩展,在测试副本验证后切换全部实例
有来源可核验的回补旧版本暂时无法迁移确认覆盖两个 CVE、构建来源和校验记录,设定迁移期限
新版本并行迁移老语法、旧库或驱动阻碍直接升级先隔离风险,再建立测试环境逐项迁移,验证后切流量

PHP 官方为 7.4、8.0、8.1 提供了最小源码回补;这更新了预警文章对旧分支修复可得性的描述。但源码补丁不等于现成 Windows 安装包,更不意味着这些分支恢复长期支持。7.4 回补、8.0 回补、8.1 回补

对于更老的版本,不能把上述回补分支当作可直接安装的补丁。没有可信回补与测试能力时,应收紧暴露面并安排受支持版本迁移。

PHP 8.2 的安全支持将在 2026-12-31 结束。它可以是受兼容条件约束的短期过渡目标,但不宜作为这次长期迁移的默认终点。PHP 支持周期

暂时不能升级,怎样降低风险 ​

首先在请求进入 PHP 之前收紧不可信访问:不需要开放的动态入口暂停开放,必要入口经过受控访问边界。仅在 PHP 应用里加登录判断,不能覆盖业务代码执行前的路径。

业务允许时,可以由运维在实际 Web worker 使用的 php.ini 或等效启动前配置里关闭 Session 上传进度,然后重启全部相关 worker:

ini
; 仅缓解已确认的 Session 上传进度路径,不是完整修复
session.upload_progress.enabled = 0

它不会关闭正常 Session 或所有文件上传,但依赖 PHP Session 上传进度的功能会受影响。要在测试环境验证普通上传与进度显示,不能只看到配置为 0 就认为业务验证通过。

不要把这个设置放进业务入口的 ini_set();也不能依赖 FPM 的 .user.ini 来赶在相关解析之前生效。PHP 8.5 另有 fatal_error_backtraces=0 的特定路径缓解,仍不能替代完整补丁。残留状态漏洞的缓解边界

为什么不直接复制 memory_limit=-1 ​

OOM 公告提出,管理级强制 memory_limit=-1 可以移除一种可预测的 PHP 内存限额失败,但底层分配失败仍有风险,且资源耗尽压力会转移到系统。它必须结合请求限制和资源边界评估,不能作为 Windows 老系统的一键安全配置;Linux cgroup 的说明也不能原样当作 Windows 操作步骤。OOM 缓解说明

案例中的运行方式、可用内存与进程隔离方式尚未核实,本文不建议先把生产 memory_limit 改成无限再观察。优先选择可信补丁或隔离;不得把无限内存写进通用业务配置示例。

WAF 和请求限制能做什么 ​

在 PHP 之前限制解码后的请求体大小、字段数量、多段表单部件和并发,有助于减少暴露与资源压力。检查应覆盖没有可靠 Content-Length 的请求,不能只限制请求头声明的长度。

案例确实有文件上传与导入业务,因此全站拒绝 multipart/form-data 会影响业务。若采用临时限制,要按入口和业务需要制定范围。关闭业务上传接口、阻断某个进度字段或开启 WAF,都不能宣称覆盖两个 CVE 的全部路径。

临时缓解需要记录负责人、覆盖实例、验证结果和失效日期;它的终点应是完成运行时修复,而不是长期保留一个“已处理”标签。

为什么这个 Yaf 项目需要兼容迁移 ​

静态检查发现的障碍可以分成四组:

类别项目里的线索建议处理
语言与函数旧魔术引号函数、动态函数构造、迭代与偏移访问对照迁移指南修复,再验证调用结果
报表与模板库旧 Excel 库被实际业务引用选择维护中的兼容实现,验证格式、公式、中文和大文件
Windows 扩展Yaf、Redis、SQL Server 驱动等按 PHP ABI、位数、TS/NTS、运行库组成匹配矩阵
历史加密数据旧加解密函数及按扩展存在性选择算法的逻辑使用脱敏测试向量验证旧数据兼容,避免随手换算法

具体发现包括 get_magic_quotes_gpc()、create_function()、旧依赖中的 each() 和花括号偏移访问。PHP 8 已移除这些函数或语法;运行时升级可能使旧文件无法加载,或在调用时直接失败。这些是源码可确认的迁移障碍,不是本次漏洞已被利用的证据。PHP 8 不兼容变更

仓库里出现旧数据库适配器,也不等于线上正在使用它。应继续追踪实际选择分支,区分“存量文件”与“生效调用链”,避免把所有历史文件都当成紧急修改范围。

新版本并不是没有 Windows 扩展可用 ​

截至本文日期,官方 Yaf 3.3.8 页面列出了 PHP 8.4、8.5 的 Windows TS/NTS、x64/x86 DLL。因此可以把 PHP 8.4/8.5 列为迁移候选;是否适用于项目,还要核实其他扩展和业务兼容。Yaf Windows 构建

Microsoft 的 SQL Server PHP 驱动支持矩阵也提供了新 PHP 版本对应关系,但仍需逐项匹配操作系统、SQL Server、ODBC 和驱动组合。不能因为一个 DLL 能加载,就跳过真实的测试库读写与事务验证。Microsoft 支持矩阵

一套可执行的升级顺序 ​

text
官方公告与版本核对
       ↓
实际 Web 运行时清单
       ↓
无法立即修补?先隔离并做有限缓解
       ↓
测试副本:完整运行时 + 匹配扩展 + 兼容修复
       ↓
业务回归、容量检查、回滚演练
       ↓
经批准切换全部实例并重启 worker
       ↓
核实实际加载版本与配置,观察异常

备份应覆盖代码、运行时、扩展、服务映射和配置,并由运维按既有流程保护业务数据。备份文件离开公开 Web 目录,凭据继续留在受控配置中;“备份成功”还要有可恢复的验证。

测试副本先阻断生产数据库、业务接口、真实邮件与支付等依赖,再启动应用。迁移回归应至少覆盖:

  • 所有应用入口和独立脚本,而不只是一个登录页;
  • Session、Cookie、权限、退出与登录态兼容;
  • 测试数据库事务、存储过程、中文、金额和空值处理;
  • 文件上传、导入导出、报表公式、条码与大文件;
  • Redis、图像处理和历史密文读取;
  • 定时任务使用的 CLI 运行时,避免只升级 Web;
  • 上线前后重复出现的启动告警、致命错误、超时和 worker 异常退出。

不要用攻击性请求撞生产来证明漏洞存在或修复成功。验证基于可信补丁、实际加载的二进制、配置生效和隔离环境回归;安全团队需要进一步验证时,也应单独界定环境与授权。

回滚不能把易受攻击版本重新暴露出去 ​

建议准备可切换的完整运行时目录和配置快照,避免原地覆盖后找不回旧扩展组合。补丁升级尽量不与数据库结构改造捆绑,以降低回滚耦合。

如果新环境出现兼容故障,回滚目标也应尽量使用已修复运行时;确实只能恢复旧版本时,必须继续保留隔离措施。恢复业务访问与撤销安全隔离,是两个需要分别判断的动作。

更新和重启完成后,由运维逐实例确认 Web worker 实际加载的版本、补丁来源和配置,再核对任务进程。磁盘里存在新文件、CLI 版本变了或某个健康页返回成功,都不足以单独证明全部实例已修复。

如果已出现不明脚本、异常子进程或其他入侵迹象,应启动独立的事件响应:先保全证据和隔离,再评估重建及凭据轮换。安装补丁不能清除已经存在的后门;日志没有异常也不能证明从未被利用。

什么结果才可以标记完成 ​

阶段可交付证据当前案例状态
公告核实CVE、修复版本、官方链接及核实日期已完成
仓库检查入口、上传、依赖和兼容障碍的静态证据已完成
环境盘点每个 Web 与任务实例的实际运行时及配置待运维提供
隔离与临时缓解覆盖范围、重启与配置生效结果未执行
升级与回归补丁来源、测试结果和切换记录未执行
修复验收全实例核验及持续观察结果未执行

这个案例最值得复用的经验是:把“看到漏洞新闻”变成一份有证据的运行时清单,再用最短可验证路径完成补丁交付。不要把升级障碍当作长期不修的理由,也不要把源码审查或一个配置开关包装成已经修复。

延伸阅读:Yaf 多应用项目怎样整理、旧系统渐进改造、环境与配置管理。

为复用而记录,为理解而整理。