PHP 发布 8.2.35 / 8.3.36 / 8.4.27 / 8.5.12,修复两个 CVSS 9.2 的未认证 RCE(PHP2Shell)
PHP 10 月 21 日发布四个修复版,修两个 CVSS v4.0 9.2 的未认证 RCE;官方称无完整缓解,只有升级。

PHP 是广泛用于服务端网页的脚本语言,PHP2Shell 是安全业界对 2026 年 10 月 21 日公开的两个 PHP 核心引擎漏洞的合称。PHP 项目当天在 UTC 14:00 之后依次发布 8.5.12、8.4.27、8.3.36 与 8.2.35 四个修复版本,修掉 CVE-2026-109618 与 CVE-2026-109619 两个未认证远程代码执行漏洞;PHP 作为 CNA 在 CVE 记录里给两者的 CVSS v4.0 评分都是 9.2。php-src 的发布说明写得很直接:「There are no complete mitigations, updating is the only safe choice.」
要点
- 四个版本的实际发布时间是 UTC 14:06:46(8.5.12)、14:07:28(8.4.27)、14:07:57(8.3.36)与 14:09:17(8.2.35),取自 GitHub Releases API;php.net 的公告编号为 2026-10-21-5。
- 官方把受影响面列为 PHP-FPM、Apache 的 mod_php、php-cgi、FrankenPHP 与 LiteSpeed 五种 SAPI,并称 mod_php 风险最高:未认证请求可以在应用代码执行之前触发攻击。
- 在野利用的结论互相矛盾。TechCrunch 转述 OpenAI 的说法是「there were no reports of exploits in the wild」,watchTowr 在 10 月 21 日 14:19 UTC 写「Exploited in the wild: Yes」,AWS 则称 MadPot 蜜罐遥测里 10 月 17 日就出现了利用尝试。
漏洞机制
两个漏洞都落在 PHP 每个请求都会经过的内存管理与错误处理路径上。PHP 遇到内存耗尽(OOM)或致命错误时用 longjmp() 跳出当前上下文,而不是逐层展开调用栈;正在执行的 C 函数可能已经把指针写进全局状态,却还没把结构体填完。请求清理阶段随后把这批半成品当成有效数据,或者后续请求复用同一个 worker 时读到上一请求留下的悬空指针。
CVE-2026-109618(GHSA-w8hw-w9fx-j79w)在官方公告里叫「RCE via OOM corruption」:内存耗尽中断 PHP 时,内部请求数据只初始化了一部分,清理过程把无效数据当有效数据处理。CVE-2026-109619(GHSA-6wmf-4rv5-p3rp)叫「RCE via stale global state」:请求持有的内部状态在背后内存被释放后仍然存活,同一 worker 处理的下一个请求可能在正常初始化重置它之前就用到。
Wiz 把四个可触发的缺陷实例归进这两个 CVE:上传进度的反序列化 use-after-free、远程进程内存泄露、致命错误回溯的 use-after-free、OPcache 类型混淆。Wiz 说内存泄露本身就能读到 PHP 进程内存里的密码、token、API key 与证书;他们用 WordPress、Drupal、Joomla 的官方最新容器镜像演示了未认证 RCE。
Calif 公布的利用细节解释了为什么普通站点也躲不开。PHP 只拿 post_max_size 跟声明的 Content-Length 比较,不校验实际读入的字节数,chunked HTTP/1.1 或不带长度的 HTTP/2 请求因此能绕过默认 8 MiB 的限制。放大手段同样简单:文件名留空的 RFC1867 上传分段没有文件内容、不计入 max_file_uploads,PHP 仍会为它生成 name、full_path、type、tmp_name、error、size 六个 $_FILES 条目;字段名嵌套成 files[a][b][c] 时,这六个条目各自要建一套层级,几 KB 的表单文本就能吃掉默认 128 MiB 的堆。
披露过程
这次披露本身也是事件的一部分。PHP Foundation 的复盘写:10 月 20 日 UTC 15:00 左右,两个 CVE 编号开始在论坛和社交平台流传,附带错误的发布时间与错误的 CVSS 10.0 评分;技术细节没有泄露。PHP 项目把预公告提前到 19:30 UTC 发布,并把发布日期从 10 月 22 日 14:00 UTC 提前一天。
同一天 UTC 20:00 前后,报告方之一 Calif 误发了一段视频,演示 PoC 在多个目标上跑通,还透露了少量额外细节;视频被删除后副本继续在社交平台流传,加速了各类 PoC 的开发。给关键基础设施厂商的缓解建议在 10 月 20 日 23:00 UTC 前后开始下发,也可能已经泄露。10 月 21 日 07:41 UTC,Chainguard 单方面打破禁令,发布了含修复的构建镜像,比协调发布时间早六个多小时。
漏洞的来源要早得多。2024 年 PHP 接受多年来的首次外部安全审计,由 PHP Foundation 通过 OSTIF 组织、Quarkslab 执行,资金来自德国主权技术署;在修 Quarkslab 报的另一个问题时,PHP 核心开发者发现了 OOM 问题的第一批迹象,当时有人推测过潜在利用方式,但没有找到具体路径。2026 年 7 月 30 日 Calif 在 OpenAI 的 Patch the Planet 项目下开始审计 PHP,8 月 11 日 Ryan A 报告了一个与 2024 年 OOM 问题同根的无条件 RCE;OpenAI 同一天独立报告了相同根因,Wiz 在 8 月 24 日提交自己的变体,OpenAI 又在 9 月 18 日补了更多攻击路径。
AI 让报告变多,也让分诊变重。PHP Foundation 说,安全团队从 7 月 1 日以来发布了 15 个 CVE,另外处理了 100 多份被判为无效、重复或无法复现的报告。开源项目被自动化报告淹没不是 PHP 一家的事:Google 在 10 月 1 日暂停了 OSS 漏洞赏金提交(见 Google 冻结开源赏金)。
修复版本
四个修复版本覆盖当前支持的 8.2 到 8.5 四条分支,7.4、8.0、8.1 没有官方构建。
| 分支 | 修复版本 | 发布时刻(UTC,2026-10-21) |
|---|---|---|
| 8.5 | 8.5.12 | 14:06:46 |
| 8.4 | 8.4.27 | 14:07:28 |
| 8.3 | 8.3.36 | 14:07:57 |
| 8.2 | 8.2.35 | 14:09:17 |
官方同时给了只能算临时措施的清单。针对 109618:把 memory_limit 设为 -1,最好放在应用改不掉的位置,例如 FPM pool 或 Apache 配置里的 php_admin_value,并确认没有 pool、目录或应用设置又把上限加回来;把 post_max_size 压低,不做文件上传的站点设 8M,需要上传的设 32M,并让 upload_max_filesize 低于它;用容器或 cgroup 限额做可用性边界,策略上只杀掉受影响的 worker。公告在这里加了一句反向提醒:不要用 RLIMIT_AS 或 RLIMIT_DATA 替代,因为它们本身就能触发那个有问题的分配失败。
针对 109619:设 session.upload_progress.enabled=0 并重启所有 worker;配置要写在 php.ini、FPM pool 或服务器配置里,在请求解析之前生效,不能依赖 ini_set() 或 FPM 的 .user.ini。PHP 8.5 上还要设 fatal_error_backtraces=0 并重启所有 worker。此外要清掉那些在初始化之前就产生诊断信息的过时或弃用配置,用 error_reporting、display_errors 或 @ 把诊断藏起来没有用;应用里可被攻击者触发的致命错误与执行超时也要修。
官方对这些措施定了性:它们只降低特定攻击路径的暴露,不能让安装变安全。唯一完整的解法是升级。
影响范围
W3Techs 在 2026 年 10 月 22 日的抓取里写,PHP 被「69.3% 的已知服务端语言的网站」使用。这个数字的分母只算 W3Techs 能识别服务端语言的站点,不代表全网网站。TechCrunch 写约 70%、超过 3300 万个站点;The Verge 引 VirusTotal 的数据说约 380 万个站点开了至少一个端口在跑 PHP。
实际影响已经落到站点上。The Verge 报道 4chan、DeviantArt、Wikipedia 当天出现故障,荷兰与芬兰的部分政府机构把站点预防性下线,Pokémon Home 与 Pokémon Champions 也下线(这部分转引 Kotaku)。美国 NSA 的网络安全账号与英国 NCSC 都建议,如果无法立即升级就把系统下线。The Verge 还引 Cloudflare 的 CTO 说「seeing early attacks emerging」。
中文侧的处置口径以云厂商为主。快科技 10 月 22 日转述腾讯云的风险通告,按 8.2、8.3、8.4、8.5 四条分支分列「低于某版本」与「建议升级到某版本」,并称腾讯 T-Sec 主机安全已支持检测,Web 应用防火墙与云防火墙已支持防护。
美国 CISA 的已知被利用漏洞目录(catalogVersion 2026.10.21,共 1754 条)里还没有这两个编号。
各方说法
在野利用的时间线是这场争议的核心。TechCrunch 的 Julie Bort 在 10 月 21 日引 OpenAI 的说法,称漏洞先被研究者发现、黑客尚未利用,因此「there were no reports of exploits in the wild」;PHP Foundation 的复盘也说,泄露后团队持续监控并检查出现的 PoC,在发布与公开披露时没有发现可用的 exploit。
watchTowr 在同一天 14:19 UTC 的通报里把「Exploited in the wild」标成 Yes。AWS 的 CJ Moses 写得更具体:Amazon Threat Intelligence 在 MadPot 蜜罐遥测里找到一次可追溯到 10 月 17 日的 PHP2Shell 利用尝试,来自与商业匿名化网络相关的 IP,比公开披露早四天;10 月 21 日 02:00 到 08:00 UTC 之间又出现多起针对 MadPot 的尝试,载荷与匿名化设施各不相同,指向多个行动者。AWS 称这些尝试是否会在真实系统上成功仍不清楚,但随后写「PHP2Shell is now being broadly exploited in the wild」。
严重性评分的分歧有明确答案。流传的 CVSS 10.0 是错的,PHP Foundation 直接点明这一点;CNA 记录与 NVD 的 v4.0 都是 9.2,向量为 CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H。NVD 另外给了 CVSS v3.1 9.8,两套标准的打分不一样,引用时要说清是哪一套。
受影响版本的范围没有统一口径。CNA 记录只列 8.2、8.3、8.4、8.5 四条分支,defaultStatus 是 unaffected;Wiz 写「过去十年发布的每个 PHP 版本」都受影响,最早回溯到 5.4;Calif 写找到的最早受影响路径起于 PHP 5.4.0;The Verge 写约 20 年;TechCrunch 写自 2004 年的 PHP 5 起。官方的修复只覆盖 8.2 到 8.5,另外给 7.4、8.0、8.1 提供了最小源码 backport。把这些说法并列时,5.4 起的部分属于研究者判断,不是官方确认。
PHP 安全团队的 Alexandre Daubois 从内部视角列了泄露版错在哪:session.upload_progress.enabled=Off 只属于 109619 的会话生命周期路径,109618 的公告根本没提 session;泄露版里几乎没人提到 memory_limit=-1 这条被官方排在第一位的临时措施;watchTowr 的版本名单写 PHP 5、6、7、8,其中 PHP 6 从未发布。
对「AI 发现」的叙事也有反面的读法。Dead Neurons 的 Nick Rogers 把时间线摆出来:漏洞源码在 GitHub 上公开了十多年,2004 年 Stefan Esser 就发现过原始的 memory_limit 中断问题,2019 年 11 月有人在 PHP 官方 bug 系统以 #78876 报过同一片 multipart 解析代码里的 OOM 与清理问题(后来编号 CVE-2019-11048),2024 年 Quarkslab 的审计又标记过一次。按 Calif 的记述,Esser 当年做出过利用但没有公开,CORE 与 Immunity 两家商业厂商各自持有非公开版本;2024 年的审计则只确认了问题、没有证明可利用。Rogers 的判断是:材料都在训练数据里,但无引导的模型没有自己把线索连起来,是研究者先带着二十年的漏洞史去提问,模型再把找变体和适配堆布局的成本从几个月压到几天。他引用 Mallory 的扫描数据说,150 万台上报 PHP 版本的公网主机里有 59%(883,717 台)跑在已停止维护的分支上。AI 压缩 exploit 开发周期的效应,本站此前在 XBOW 用 GPT-5.6 六天拼出 Chrome 全链 里记录过一次。
编辑判断
这次事件对运维的实际含义,是补丁窗口从「天」缩到了「小时」。AWS 的判断值得抄进值班手册:对暴露在公网的严重漏洞,按小时算补丁与缓解时间;调查起点要放在已知最早利用时间,PHP2Shell 这个案子至少从 10 月 17 日查起。
第一分钟能做的事很朴素:跑一次 php -v 或看 phpinfo,确认在跑哪条分支。8.2 到 8.5 直接升到 8.5.12、8.4.27、8.3.36 或 8.2.35;用发行版或 LTS 厂商的包就查厂商的更新;跑官方 Docker 镜像的,把基础镜像标签换到对应版本重建,别只改 composer 里的依赖。
有几个限制需要先说清。缓解清单不能替代升级,官方自己写了这些措施只降低特定攻击路径的暴露。7.4、8.0、8.1 只有最小源码 backport,没有官方构建,自己编译的团队要评估维护成本,共享主机用户则只能等主机商。PHP 8.2 将在 2026 年 12 月 31 日停止支持,这次修完到年底还有两个多月的窗口,之后 8.2 上的站点会再次失去官方补丁。
还不清楚的地方也要留白:10 月 17 日那次蜜罐尝试的行动者如何提前拿到利用信息,AWS 说仍不清楚;那些尝试是否成功,也没有定论;5.4 起的受影响范围只有研究者演示支撑,官方没有为老版本发构建。这些答案出现之前,把版本升到最新、把 memory_limit 与上传配置按公告调一遍,是可执行的部分。补丁本身也是情报,修复 PR 公开十分钟就遭探测的案例(见 修复 PR 公开 10 分钟即遭探测)说明攻击者盯着 diff 看。