安全通告 · CVE-2026-109618 / CVE-2026-109619 · 2026-10-22
昨晚十点(2026-10-21 22:00),PHP 官方发布紧急安全更新,修复两个被安全社区统称为 PHP2Shell 的远程代码执行漏洞——CVE-2026-109618 与 CVE-2026-109619。两项评分都是 CVSS v4.0 9.2(严重),共同点是攻击者不需要任何账号密码,就能让服务器替他执行任意代码。安全公司 Sansec 披露,watchTowr 复现确认,WordPress、Magento、WooCommerce 等各类 PHP 应用全在射程内。
更麻烦的是时间差:按安全社区的说法,补丁发布约 15 分钟内,全网规模的自动化扫描就会跟上。补丁昨晚已经发布,所以别再问「来不来得及」,今天要做的是三件事:对号入座、升级、验证——最后一件事是本文的重点。多数通告讲完升级就停笔了,但「升了」和「真的安全了」之间,还隔着好几个坑。
一、这两个漏洞是怎么回事
CVE-2026-109618:内存耗尽处理异常。PHP 在处理内存耗尽(OOM)异常时,部分内部请求数据没有正确初始化,后续清理过程中被错误使用。通俗讲:PHP 快被撑爆的时候脑子会乱,攻击者只要精心构造一份让内存恰好爆掉的请求,就能让引擎在混乱中执行他的代码。
CVE-2026-109619:全局状态残留。PHP 处理完一个请求后,部分内部状态没被清干净,同一个工作进程继续服务下一个请求时,可能错误使用这些已失效的数据。PHP-FPM 和 Apache mod_php 都是常驻进程、连续服务成千上万个请求,所以这个坑对它们格外致命。
影响范围:PHP 5.4 及以上所有版本;运行环境覆盖 PHP-FPM、Apache mod_php、php-cgi、FrankenPHP、LiteSpeed。其中 mod_php 风险尤其突出——官方已有「在应用代码运行之前」就能触发漏洞的验证案例,攻击请求到达即中招,网站代码本身有没有漏洞都无所谓。
二、对号入座:你的版本该升到哪
官方修复版(2026-10-21 发布,对应分支当前最新版):
| PHP 分支 | 安全修复版本 |
|---|---|
| PHP 8.2 | 8.2.35 |
| PHP 8.3 | 8.3.36 |
| PHP 8.4 | 8.4.27 |
| PHP 8.5 | 8.5.12 |
PHP 官方只发布了 8.2 以上分支的安装包;7.4、8.0、8.1 只有源码补丁。宝塔面板已应用补丁并打包发布,直接在软件商店升级即可:
| PHP 分支 | 宝塔修复版本 |
|---|---|
| PHP 7.4 | 7.4.34 |
| PHP 8.0 | 8.0.27 |
| PHP 8.1 | 8.1.35 |
注意:PHP 8.1 及更早版本已停止官方安全维护,宝塔这次打包算救急,长期方案仍然是迁移到 8.2 以上。还在用 7.x、5.6 的非宝塔用户没有这份救急,迁移是唯一出路。
三、宝塔面板怎么升
1. 登录宝塔面板,进入「软件商店 → 已安装」;
2. 先点右上角「更新软件列表」——这一步不能省,不更新列表就看不到新版本;
3. 找到网站正在使用的 PHP 版本,点「更新」升到对应修复版;
4. 多版本环境逐个检查:面板里可能装着好几个 PHP,每个站点实际绑定的版本在「网站 → 设置 → PHP 版本」里逐站确认,别只升了没人用的那个;
5. 升级前备份网站和数据库,挑业务低峰操作。
四、命令行怎么升(Debian/Ubuntu)
apt update apt upgrade systemctl restart php8.4-fpm systemctl reload nginx
容易踩的第一个坑:官方源的修复不一定叫 8.4.27,可能是 8.4.26-1+deb13u2 这种「回补版本」——版本数字没变,但漏洞已经修了。所以别死等某个版本号出现,用这条确认有没有新包在等你:
apt list --upgradable 2>/dev/null | grep -i php
第二个隐蔽的坑:OPcache 是独立组件,不重启 fpm 它还会用旧代码。升完两个都确认,两个版本号都变新了才算生效:
php -v php --ri "Zend OPcache" | grep -i version
五、暂时升不了怎么办:缓解与误区
官方原话:本次漏洞不存在能完全替代安全更新的临时缓解方案。缓解只是给「今晚真的升不了」的窗口期续命。
针对 109619:关掉 Session 上传进度跟踪。在 php.ini 中设置 session.upload_progress.enabled = 0(PHP 8.5 还可加 fatal_error_backtraces = 0)。关键在生效位置:必须用 php.ini、FPM 池配置或服务器配置——这些在请求解析前生效;应用代码里的 ini_set() 和 FPM 的 .user.ini 都是请求中才生效,等于没改。改完重启对应 PHP 服务。
针对 109618:收紧 POST 体积与内存限制。post_max_size 按业务调小(无大文件上传参考 8M,有上传参考 32M,并确保 upload_max_filesize 小于 post_max_size)。有运维经验的,可在容器或 cgroup 内存隔离到位的前提下评估 memory_limit = -1——取消 PHP 自身内存上限,让「撑爆内存」这条触发路径本身失效;没有资源隔离别碰,也别用 RLIMIT_AS/RLIMIT_DATA 代替,那反而会触发同样的内存分配失败。Web 服务器层可再限制一次请求体大小,并覆盖没有 Content-Length 的请求。
网络层止损:站点套了 Cloudflare 的,防火墙只放行 CF 回源 IP 段,源站其余直接 403,让攻击流量必须先过 CF;确认托管规则集(managed ruleset)处于开启状态。
两个没用的操作,再强调一遍:改 php.ini 禁用 exec、system 之类的函数——没用,漏洞在引擎层,利用过程不经过这些函数;装在 PHP 里跑的安全插件——没用,它们自己就在被攻击的那个进程里。网络层 WAF 有用,但只是止损,不是修复。
六、升级之后,怎么亲手验证漏洞没了
这是本文的重点。「升完了」和「真的安全了」之间隔着六个坑,逐个过。
6.1 别只用 php -v 验证——CLI 和 FPM 是两套二进制
php -v 验证的是你在 SSH 里敲的那套 PHP;网站真正跑在 FPM 池上,是另一套二进制、另一份 php.ini。两套可能同时存在,还可能版本不同。都要查:
php -v php-fpm8.4 -v # 宝塔用户(目录按版本号取后两位,示例为 8.4): /www/server/php/84/bin/php -v
6.2 回补版本看 changelog 里的 CVE 编号
Debian/Ubuntu 的回补版本数字不动,怎么确认修没修?changelog 是硬证据——安全修复的变更记录里会写 CVE 编号:
dpkg -l | grep -i php apt changelog php8.4-cli | grep -i "CVE-2026-1096"
第二条命令有输出(列出 CVE-2026-109618 / CVE-2026-109619),说明这份包已包含本次修复;一片空白,说明源还没同步或包没升到位。这是判断「回补版本修没修」最可靠的证据。
6.3 用 phpinfo 临时页做最终裁决
版本核对做完了还不够——缓解配置是否生效,要看 FPM 运行时的实际值。在网站根目录放一个文件(比如 check.php),内容一行:
<?php phpinfo();
浏览器访问后核对三处:一是 PHP Version,是不是对应修复版;二是 Loaded Configuration File,这是 FPM 实际加载的 php.ini 路径——确认你改的就是这份文件;三是 session.upload_progress.enabled 与 post_max_size 的 Master Value,缓解配置是不是真的在 FPM 里生效。看完立刻删掉这个文件——phpinfo 页会把路径、版本、扩展全家桶亮给任何访问者,留着它等于给扫描器递地图。
6.4 确认 FPM 真的重启过
升级只换了磁盘上的文件;FPM 是常驻进程,内存里的旧引擎会一直服务到你重启为止。两条命令交叉验证:
systemctl show php8.4-fpm --property=ActiveEnterTimestamp ps -eo pid,lstart,cmd | grep -i php-fpm
ActiveEnterTimestamp 必须晚于昨晚 22:00(补丁发布时间);worker 进程的启动时间也逐个看一眼——如果时间戳还停在补丁发布之前,说明刚才的「升级」只动了磁盘,内存里跑的还是旧引擎。
6.5 别指望「检测插件」
和第五节的误区一脉相承:任何用 PHP 写的漏洞检测脚本、安全插件,自己就跑在被攻击的那个进程里,检测不了能把宿主一起打穿的引擎层漏洞。这个漏洞可靠的验证只有两条路:本文 6.1 到 6.4 的版本与配置核对,以及之后几天盯日志——WAF 拦截记录和 PHP 错误日志里的异常请求。这段时间全网扫描密度最高,有拦截记录反而说明防线在干活,静悄悄不代表没人来过。
6.6 功能回归
最后把业务过一遍:首页和一篇内页正常打开、后台能登录、发一篇测试文章、传一个测试文件(尤其刚调过 post_max_size 的);开了页面缓存的顺手清一次,让新引擎生成的页面生效。
七、顺手把 Node.js 也升了
同一天 Node.js 官方也发布了安全更新,共修复 10 项漏洞(4 高危、3 中危、3 低危),含远程代码执行与 TLS 证书校验绕过。重点记一个:CVE-2026-111497,Brotli 解码器越界写入,可实现远程代码执行。
| Node.js 分支 | 安全修复版本 |
|---|---|
| 22.x | 22.23.4 |
| 24.x | 24.22.1 |
| 26.x | 26.12.1 |
宝塔用户在「软件商店 → Node.js 版本管理器」里点「更新版本列表」,安装对应版本。注意:安装新版本不会自动切换项目——装完要把项目切到新版本并重启服务,才算生效。
八、写在最后
这场仗的时间线值得回味:补丁发布 15 分钟,全网扫描就位。安全这件事里,「知道有漏洞」和「确认自己没漏洞」是两回事,中间隔着版本核对、进程重启、配置生效这些枯燥的工序。今晚把第六节的清单跑一遍,跑完再睡。
本文漏洞信息基于 2026-10-21 PHP 官方安全公告、Sansec 与 watchTowr 公开披露、宝塔面板官方公告(2026-10-22 更新)整理;版本号与修复方案以官方最新说明为准,各发行版源同步有延迟,升级前建议再核对一次版本号。
评论 (0)