PHP 爆出两个可以远程执行代码的严重漏洞:该升到哪个版本,OpenAI 给的检查工具实测
PHP 官方 10 月 21 日发布 8.5.12、8.4.27、8.3.36、8.2.35,修了两个不用登录就能远程执行代码的漏洞。OpenAI 同时开源了一个检查网站 PHP 版本的 Codex skill。本站在服务器上实测了这个工具,它只看响应头,有几种情况会误判。
2026 年 10 月 21 日,PHP 官方发布安全公告:两个严重漏洞可以让攻击者不用登录就远程执行代码,所有用 PHP 处理网页请求的服务器都受影响,要求立即升级。修复版本是 8.5.12、8.4.27、8.3.36 和 8.2.35。
同一天,OpenAI 说这两个漏洞是它的“Patch the Planet”计划里发现的,并把一个检查网站 PHP 版本的工具做成了 Codex 的 skill,开源在 GitHub 上。本站 10 月 22 日在服务器上实测了这个工具:它能帮你快速筛一遍,但只看 HTTP 响应头,有几种情况会误判,最后还是要在服务器上核对。
先说要做什么
- 能升级的,立即升级到 8.5.12、8.4.27、8.3.36 或 8.2.35。
- 用的是发行版或 LTS 厂商的包(Ubuntu、Debian、RHEL 这类):官方说这些厂商提前拿到了补丁,去看你的发行版有没有发更新的包。
- 还在用 8.1 或更早的版本:PHP 官方已经不再给这些版本发更新。官方这次破例给 7.4、8.0、8.1 出了最小的源码补丁,方便自己编译的人;更稳妥的是升到还在维护的版本,或者问你的发行版厂商有没有移植修复。
- 暂时升级不了:官方给了一些缓解办法,见下文。官方的原话是:只有升级才是完整的解决办法,这些办法只能减少某些攻击途径。
两个漏洞
| 编号 | 官方的名字 | 简单说 |
|---|---|---|
| CVE-2026-109618(GHSA-w8hw-w9fx-j79w) | RCE via OOM corruption | 内存不够时的处理会在请求数据只初始化了一半的时候打断 PHP,之后清理请求时把无效的数据当成有效的用 |
| CVE-2026-109619(GHSA-6wmf-4rv5-p3rp) | RCE via stale global state | 属于某个请求的内部状态,在它的内存释放以后还留着;同一个工作进程处理下一个请求时,可能在正常初始化之前用到它 |
谁有风险: 官方的说法是所有处理网页请求的 PHP,包括 PHP-FPM、Apache 的 mod_php、php-cgi、FrankenPHP 和 LiteSpeed。mod_php 的风险最高,官方演示过一个未登录的请求就能在任何应用代码运行之前触发攻击。只在命令行里跑 PHP 脚本、不对外提供网页的,不在官方点名的范围里。
哪些版本受影响
OpenAI 的检查工具里写着它按什么范围判断(截至 10 月 20 日),对照 PHP 官方的修复版本:
| 分支 | 工具判为受影响的版本 | 官方的修复 |
|---|---|---|
| 8.5 | 8.5.0 到 8.5.11 | 8.5.12 |
| 8.4 | 8.4.0 到 8.4.26 | 8.4.27 |
| 8.3 | 8.3.0 到 8.3.35 | 8.3.36 |
| 8.2 | 8.2.0 到 8.2.34 | 8.2.35 |
| 8.1 | 8.1.0 到 8.1.34 | 官方不再发版本;给了最小的源码补丁 |
| 8.0 | 8.0.0 到 8.0.30 | 同上 |
| 7.4 | 7.4.0 到 7.4.33 | 同上 |
| 7.3 及更早(工具列到 5.4) | 全部 | 官方不再维护,也没有给补丁 |
发行版的包常常是旧版本号加上移植过来的修复,版本号看着旧,不一定有漏洞,要以发行版自己的安全公告为准。
暂时升级不了:官方的缓解办法
官方按两个漏洞分别给了办法,都只是减少暴露面:
针对 CVE-2026-109618:
- 把
memory_limit设成-1,最好用应用改不掉的方式设,比如 FPM 池或 Apache 配置里的php_admin_value,并检查没有哪个池、目录或应用又设回了一个有限的值。官方提醒这只是去掉了可控的那条内存上限失败路径,底层的内存分配失败仍然可能走到漏洞。 - 调低
post_max_size:不需要上传文件的设成8M,需要上传的设成32M,upload_max_filesize要小于它。 - 在 Web 服务器或代理这一层限制解码后的请求大小、表单字段数、multipart 的分段数、请求头数量和嵌套深度,没有可用
Content-Length的请求也要限制。 - 用容器或 cgroup 的内存上限兜底,最好只杀掉出问题的那个工作进程。不要改用
RLIMIT_AS或RLIMIT_DATA,它们本身就可能引发这个漏洞要的那种内存分配失败。
针对 CVE-2026-109619:
- 设
session.upload_progress.enabled=0,然后重启所有工作进程。要写在请求解析之前就生效的地方(php.ini、FPM 池或服务器配置),不能靠ini_set()或 FPM 的.user.ini。这只挡住已经确认的 session 这条路径。 - PHP 8.5 上再设
fatal_error_backtraces=0并重启所有工作进程,只挡住致命错误回溯这一条路径。 - 去掉每个请求都会套用、而且会在初始化之前报诊断信息的无效或过时设置;用
error_reporting、display_errors或@把诊断信息藏起来没有用。 - 修掉攻击者能触发的致命错误和执行超时,包括回调、上传或导入处理、清理过程中的失败。
用 OpenAI 的检查工具筛一遍
工具在 GitHub 的 openai/php2shell-checker(Apache 2.0 许可证),里面是两个 Codex skill:
phpcheck-url:只有网址的时候用,读网站返回的响应头判断版本。phpcheck-server:能登录服务器的时候用,从php -v开始,并提醒你核对它和网站实际用的 PHP-FPM 或 Apache 是不是同一个。
在 Codex 里装这两个 skill,按 README 的写法对 Codex 说:
$skill-installer install both skills from https://github.com/openai/php2shell-checker
然后用 $phpcheck-url check https://你的网站 或 $phpcheck-server check the PHP version serving my site。不用 Codex 也行,它就是一个 Node.js 脚本,可以直接跑:
node phpcheck.js "https://你的网站"
node phpcheck.js --local # 查本机命令行的 php
node phpcheck.js --json "https://你的网站"
结果有三种:OK(退出码 0),VULNERABLE(退出码 1),UNKNOWN(退出码 3)。
本站实测
10 月 22 日在本站的 Linux 服务器上(Node.js 22),把仓库固定在 10 月 21 日的提交 40a4746,先跑它自带的测试,39 项全部通过。然后起一个只在本机监听的假服务器,按不同的路径返回不同的响应头,模拟各种网站,没有扫任何真实的网站:
| 假网站返回的头 | 工具的结论 |
|---|---|
X-Powered-By: PHP/8.3.35 |
VULNERABLE: PHP 8.3.35 |
X-Powered-By: PHP/8.3.36 |
OK: PHP 8.3.36 |
X-Powered-By: PHP/8.4.27 |
OK: PHP 8.4.27 |
X-Powered-By: PHP/7.4.33 |
VULNERABLE: PHP 7.4.33 |
X-Powered-By: PHP/8.1.34 |
VULNERABLE: PHP 8.1.34 |
X-Powered-By: PHP/8.1.2-1ubuntu2.22(Ubuntu 包的写法) |
VULNERABLE: PHP 8.1.2-1ubuntu2.22 |
Server: Apache/2.4.58 (Ubuntu) PHP/8.2.35 |
OK: PHP 8.2.35 |
只有 Server: nginx,没有 PHP 版本 |
UNKNOWN: PHP version not found |
| 301 跳转到一个受影响版本的页面 | UNKNOWN: PHP version not found |
HEAD 请求回 405,GET 才有 PHP/8.4.26 |
VULNERABLE: PHP 8.4.26 |
X-Powered-By: PHP/8.6.0RC4 |
UNKNOWN: PHP 8.6.0RC4 |
--json 的输出是 {"patch_status":"vulnerable","php_version":"8.3.35","reason":"PHP 8.3.35","exit_code":1}。--local 在没装 PHP 的机器上报 UNKNOWN: spawnSync php ENOENT;换一个假的 php 打印 PHP 8.4.26 (cli),报 VULNERABLE: PHP 8.4.26。
几点要注意,和它 README 里写的一致:
UNKNOWN不等于安全。 大多数正式网站会把X-Powered-By关掉,这时它只能报UNKNOWN。它也不跟随跳转,网址如果跳到https或者别的路径,要直接给最终的网址。- 发行版的包会被误判成有漏洞。 上表 Ubuntu 那一行,版本号里的
8.1.2落在受影响的范围内,它就报VULNERABLE,不管 Ubuntu 有没有移植修复。用发行版包的,要查发行版的安全公告和包的完整版本号。 OK只是比了版本号。 它假设每个分支后续的正式版本都带了修复,并不真的验证。响应头也可能被改过。
本站的服务器上没有装 Codex,这次测的是 skill 里用的同一个脚本,没有在 Codex 里装 skill 走一遍。最可靠的检查还是登录服务器,看网站实际用的那个 PHP(PHP-FPM 或 Apache 模块,不一定和命令行的 php -v 一样)是什么版本、是哪个包。
这两个漏洞是怎么发现的
按 OpenAI 的说法:在它的 Patch the Planet 计划里,安全公司 Calif 用 GPT-5.6 Sol 找到了一个严重缺陷,Wiz 也独立发现并报告了这两个漏洞。修复由 PHP 的维护者主导,OpenAI 和 Wiz、Cloudflare 等合作方在公开之前协调了两个月,帮着准备修复和防护。OpenAI 称这是近年影响最大的安全问题之一,并说接下来几个月这类由 AI 找到的漏洞会大幅增加。
X 上给 OpenAI 这条推文加的社区备注认为,最早的发现和利用代码出自一位独立研究者,时间比这早几个月。发现者是谁,本站没有核实。
想用 AI 查自己的代码有没有漏洞,可以看本站的《用 Claude 给自己的代码找漏洞再修好》。
来源
- Security advisory: Critical remote code execution vulnerabilities, update now(php.net)
- GHSA-w8hw-w9fx-j79w:RCE via OOM corruption(php-src 安全公告)
- GHSA-6wmf-4rv5-p3rp:RCE via stale global state(php-src 安全公告)
- Patch the Planet: global response coordination as agents uncover critical vulnerabilities(OpenAI)
- openai/php2shell-checker(GitHub)
- Patch the Planet 网站
- @OpenAI:PHP 漏洞的发现和协调修复