PHP2Shell 修复 · 升级指南
如何修复 PHP2Shell
修复方法就是升级 PHP 再重启。任何配置修改、插件更新或 WAF 规则都替代不了它。这里有各常见平台的命令,以及如何证明补丁真的生效了。
最后核实 2026-10-22
目标版本
8.5.12、8.4.27、8.3.36、8.2.35 或更高——或者 changelog 中列出 CVE-2026-109618 和 CVE-2026-109619 的操作系统厂商软件包。PHP 8.1 及更早版本不会再有新版本——见下文。
| 分支 | 存在漏洞 | 修复版本 |
|---|---|---|
| 8.5 | < 8.5.12 | 8.5.12 |
| 8.4 | < 8.4.27 | 8.4.27 |
| 8.3 | < 8.3.36 | 8.3.36 |
| 8.2 | < 8.2.35 | 8.2.35 |
| 8.1 · 8.0 · 7.4 | 全部 | 仅源码回移植 |
| 5.4 – 7.3 | 全部 | 无修复 |
1. 找出所有 PHP 运行环境
遗漏的运行环境是整批服务器迟迟无法修复的最常见原因。请在每台主机上执行以下命令。
# PHP processes running right now, and when they started
ps -eo pid,lstart,cmd | grep -E '[p]hp-fpm|[h]ttpd|[a]pache2|[f]rankenphp|[l]sphp'
# CLI and FPM can be different builds — check both
php -v
ls /usr/sbin/php-fpm* 2>/dev/null && for f in /usr/sbin/php-fpm*; do "$f" -v | head -1; done
# Is Apache running PHP in-process (mod_php)? That is the highest-risk setup.
apachectl -M 2>/dev/null | grep -i php
# PHP version inside every running container
docker ps --format '{{.Names}}' | while read c; do
printf '%s: ' "$c"; docker exec "$c" php -r 'echo PHP_VERSION, PHP_EOL;' 2>/dev/null || echo 'no php'
done另外别忘了检查镜像仓库里的基础镜像、CI runner、预发和预览环境、内置 PHP 的设备,以及没人管的老服务器。从外部看,curl -sI https://site | grep -i x-powered-by 有时能看到版本号,但大多数网站会隐藏它。 可用 NCSC-NL 产品清单 排查内置 PHP 的产品,再向各厂商确认修复状态。
2. 安装已修复版本
适用于系统自带软件包和 Ondřej Surý 的 PPA / packages.sury.org。Debian/Ubuntu 自带软件包会保留旧的上游版本号并回移植补丁,所以要以 changelog 检查结果为准。
sudo apt update
# Upgrade only the PHP packages that are installed
sudo apt install --only-upgrade $(dpkg-query -W -f='${db:Status-Abbrev} ${binary:Package}\n' 'php*' | awk '$1=="ii"{print $2}')
# Proof the fix is in: the changelog should mention the CVE
# (replace 8.3 with your version)
apt changelog php8.3-common 2>/dev/null | grep -m1 -E 'CVE-2026-10961[89]' || echo 'NOT FIXED in this package yet'3. 重启所有运行 PHP 的进程
安装软件包只会替换磁盘上的文件。正在运行的进程在重启之前,仍在执行旧的、有漏洞的代码。
# Debian / Ubuntu (adjust the version)
sudo systemctl restart php8.3-fpm
sudo systemctl restart apache2 # if using mod_php
# RHEL family
sudo systemctl restart php-fpm httpd
# Anything still mapped to the old, deleted PHP binary needs a restart
sudo grep -l -E '(php|libphp)[^ ]* \(deleted\)' /proc/[0-9]*/maps 2>/dev/null
sudo needrestart -r l # Debian/Ubuntu helper, if installed
# Long-running PHP workers
php artisan queue:restart # Laravel queues
php artisan octane:reload # Octane (Swoole / RoadRunner / FrankenPHP)
sudo supervisorctl restart all # supervisor-managed workers4. 从 Web 服务器的视角验证
# Version of the FPM binary that actually serves traffic
php-fpm8.3 -v 2>/dev/null || php-fpm -v
# Compare process start times with when you upgraded
ps -o pid,lstart,cmd -C php-fpm8.3,php-fpm,apache2,httpd
# Ask the web server itself (use a random name, delete straight after)
F="v-$(openssl rand -hex 8).php"
echo '<?php echo PHP_VERSION;' | sudo tee /var/www/html/$F >/dev/null
curl -s https://your-site.example/$F; echo
sudo rm /var/www/html/$F打补丁后的新行为
补丁把内存耗尽时的中断改成在安全点检查的软限制,并新增一个更高的硬内存限制,一旦触及就用 _exit() 立即结束进程。触及硬限制时,关闭函数和析构函数都不会运行。如果你的应用在 register_shutdown_function 里做了工作(写日志、清理),升级后请测试内存消耗大的路径。
还在用 PHP 8.1、8.0、7.4 或更早版本?
这些分支已经停止支持,PHP 项目不会再为它们发布新版本,但鉴于漏洞的严重性,官方发布了最小化的源码回移植。
- 最佳方案:迁移到 PHP 8.4 或 8.5。如果时间紧,从 8.1 升到 8.3 跨度更小(8.2 将在 2026 年底结束支持)。
- 系统软件包:Ubuntu(含 Ubuntu Pro / ESM)、Debian LTS、RHEL 及其他长期支持厂商都提前拿到了补丁。按上文方法在软件包 changelog 中查找 CVE 编号。
- 自行编译:PHP 团队提供的回移植分支——PHP 8.1, PHP 8.0, PHP 7.4。它们只修复这两个 CVE,分支本身仍不受支持。
- 更早的分支:PHP 项目未列出低于上述范围的源码回移植,但发行商仍可能提供补丁:Ubuntu 已确认提供修复包,包括通过 Pro / ESM 支持的旧分支。确认补丁覆盖两个 CVE 并重启工作进程;若无已修复构建,应隔离主机并迁移。
5. 然后
相关页面
- 版本检测粘贴 php -v 输出或版本列表,立即判断每个 PHP 构建对 PHP2Shell 是否存在漏洞、已修复、已停止支持,还是发行版回移植版本。
- 临时缓解暂时无法升级时的 PHP2Shell 缓解措施:memory_limit、post_max_size、上传进度、fatal_error_backtraces、cgroup 内存上限——各自能挡住什么、会带来什么副作用。
- 主机商使用虚拟主机或托管主机时你无法自己升级 PHP。如何在 cPanel、Plesk 等面板里查看和切换 PHP 版本、各主机商的公开表态,以及该向他们问什么。
- 入侵排查PHP2Shell 利用迹象、现在就能执行的日志排查命令、安全厂商的检测规则,以及发现入侵迹象后该怎么处置。
- Cloudflare WAFCloudflare 针对 PHP2Shell 的免费版与付费版 WAF 规则 ID、如何确认规则已启用并处于拦截状态,以及为什么在 Cloudflare 后面仍然必须升级 PHP。
- session.upload_progress为什么关闭 session.upload_progress 只能部分缓解 PHP2Shell,要在哪里设置才真正生效(不能用 .user.ini 或 ini_set),如何检查,以及改完要重启什么。