PHP远程执行漏洞修复前,先找全运行时
材料称PHP修复了CVE-2026-109618和CVE-2026-109619两项无需认证的远程代码执行漏洞。文章介绍用Sourcegraph Deep Search定位代码中的PHP运行时,再通过Agentic Batch Changes批量升级。
完整中文译文
PHP 的高危漏洞修复,难点可能不在升级,而在找齐运行它的地方。Sourcegraph 这篇文章借 php2shell 提出一个判断:能否从代码追溯运行时、构建入口和负责人,决定了一次漏洞响应会变成批量提交,还是漫长的跨团队排查。
它给出的路线很实用:先查部署现场,再找源码里的版本来源,最后批量升级并验证。不过,漏洞通报、处置建议和产品宣传混在了一起,需要分开看。
应用代码没问题,为什么仍然可能中招
按原文通报,php2shell 包含 CVE-2026-109618 和 CVE-2026-109619,均为无需身份验证的远程代码执行漏洞(RCE),CVSS v4 评分都是 9.2。
问题出在 PHP 解释器处理请求的生命周期里,属于内存安全漏洞。在 mod_php 模式下,攻击路径可以在应用代码执行前触发,一个特制的 multipart POST 请求就足以启动攻击链。因此,业务层的参数校验不能替代运行时升级。
原文称,PHP 于当天 14:00 UTC 发布修复,版本分别是 8.5.12、8.4.27、8.3.36 和 8.2.35,对应公告包括 GHSA-w8hw-w9fx-j79w、GHSA-6wmf-4rv5-p3rp。PHP 8.1 及更早版本已不受上游支持。
这些信息来自原文,所给材料没有独立核验过程。原文援引 PHP 的建议是:不存在完整缓解措施,更新才是安全选择。对于通过发行版软件源安装的 PHP,还要核对发行版是否回移了补丁,不能只凭上游版本号判断。
这次需要确认的是处理请求的 PHP 二进制是否已修复。
为什么搜到 PHP,还不等于找齐了 PHP
作者列出的入口远不止 PHP 项目:官方 php:* 基础镜像、Dockerfile 中的系统包安装、WordPress 或 Matomo 的 Helm chart、运行 Composer 的 CI 镜像,以及某个人在 2019 年部署后就没人再提的管理工具。
这些入口分别把版本写在不同位置。扫描器能看到当前部署的组件,却未必能回答:哪个仓库构建了它,谁负责,下次构建是否还会装回旧版本?
文章提供了五条 Sourcegraph 查询,分别寻找基础镜像、系统包安装、Kubernetes 配置、CI 和 Composer 约束:
file:(^|/)Dockerfile patterntype:regexp ^FROM\s+\S*php
patterntype:regexp (apt-get|apt|apk|yum|dnf)\s+install.*\bphp
file:\.ya?ml$ patterntype:regexp image:\s*\S*(php|wordpress|drupal|nextcloud|matomo)
file:^\.github/workflows/ patterntype:regexp php-version|setup-php
file:composer\.json "php"
要留意最后一行:composer.json 里的 PHP 约束表达应用声明支持什么版本,不能证明线上实际运行什么。第一行也只能命中符合写法的基础镜像,内部封装过的镜像仍需继续追溯。
正则适合找已知字符串。遇到「哪些服务通过 mod_php 承接流量」「哪些内部基础镜像源自 php:7.4」这类问题,就需要跨文件追踪。
Sourcegraph 为此推荐 Deep Search:用自然语言提出问题,由它执行代码搜索和导航,并附上作为依据的文件链接。文章给出的示例,是列出所有安装或固定 PHP 版本的 Dockerfile、Helm chart 和 CI workflow。

这里的价值是获得带来源的初始清单。它仍需要与真实部署核对,才能成为完整资产清单。
升级结束,要以正在运行的进程为准
原文建议,公网暴露且运行受影响版本的主机,应按可能已被入侵处理。处置顺序是先修 mod_php,因为这是文中确认的应用执行前攻击路径,再处理 FPM、FrankenPHP 和 LSAPI。
装完新包还不够,所有 worker 都要重启。磁盘上的解释器更新了,旧进程仍可能继续运行。原文要求执行前面提到的 /proc 检查,但提供的正文没有这段命令;同样,末尾提到的崩溃模式和可疑文件清单也缺失,不能据此拼出完整检测流程。
对于暴露服务,文章还建议先保存日志、制作主机快照,再重建;轮换 Web 进程账户可读取的数据库凭据、.env 中的 API key,以及主机或元数据端点可访问的云凭据。发现访问迹象后,应进入事件响应流程。
构建链路也得一起修。只重新部署旧镜像,无法保证下一次发布使用新解释器。固定标签要更新,基础镜像要重新拉取,最终镜像要重新构建。
当清单里有 200 处旧版本引用时,批量改动才成为主要工作量。文章介绍的 Agentic Batch Changes 会结合 Deep Search 与 Code Search 定位仓库,用脚本处理机械替换,在需要判断时使用 Claude Code 或 Codex;先做小范围试改,根据 CI 失败调整,再集中跟踪各仓库的 PR。

PHP 8.1 和更早分支则需要隔离或迁移。跨分支升级可能涉及兼容性修改,不能等同于替换一个镜像标签。原文还建议将暴露主机的排查时间至少追溯到 10 月 20 日,即其所称漏洞消息首次泄露的时间。
我的判断
我认同文章把重点放在「运行时从哪里来」。漏洞扫描解决发现问题,代码追溯帮助找到持久修复入口,两者应该互相补充。对于同时维护 Node 服务和 PHP 配套系统的全栈团队,这种责任划分尤其有用。
但文章没有给出修复前后的耗时对照、搜索漏报率,也没有证明批量 PR 最终全部部署成功。「复杂代码库可能耗时数小时到数月」「多数团队本周内能完成修复」都属于作者判断,不能当成实测结论。
Deep Search 和 Agentic Batch Changes 的截图展示了操作方式,没有验证资产发现的完整性或升级的正确性。普通代码搜索配合脚本、依赖更新机器人和人工审核,也可以完成其中一部分工作;自然语言工具是否更省事,要看仓库规模和依赖关系有多绕。
PR 可以合并,只能证明代码改动过关,不能证明线上旧进程已经消失。
这条边界,比选择哪个 AI 编程工具更重要。
能拿来做什么
- 先从 Dockerfile、部署 YAML、CI 和 Composer 约束建立 PHP 清单,再补上构建仓库、负责人和线上服务的对应关系,避免只留一张版本表。
- 让 AI 搜索或编程助手逐项列出版本来源文件,再人工追踪内部基础镜像;把结果当作排查起点,并与部署现场交叉核对。
- 批量升级时,将标签替换、跨分支兼容修改和部署验证分别安排检查点。让脚本承担确定的替换,让 Claude Code 或 Codex 辅助需要阅读代码的部分。
- 将镜像重建、worker 重启和实际运行版本确认写进完成条件。公网暴露过的服务,还应按原文建议保留证据并检查凭据暴露范围。