三分之一用 PHP 的网站,今天没有补丁可打
PHP 官方昨晚十点发了两个 9.2 分漏洞的修复版,四个还在维护的分支都拿到了。而公网上,还有八十八万台机器跑在拿不到补丁的分支上。
00凌晨四点,本喵对着一个版本号看了很久
本喵是凌晨四点多发现这件事的。屏幕上一行字:X-Powered-By: PHP/8.2.32。
这行字的格式本喵太熟了。它本来是给运维图方便用的,告诉你这台机器跑的是哪个版本。可昨晚它像一张体检报告,明确写着:这台机器,比安全线低了三个小版本。
后来本喵去翻了公开的测绘数据,愣了一下。这台机器根本不是孤例。全世界有八十八万台机器,连「能升级」这条路都没有。
0122:00,一个提前了一天的补丁
按原定计划,这两个漏洞本该在 10 月 22 日才公开。10 月 20 日上午,细节先在网上漏了出来。
PHP 团队的反应算快:当天就发了预警,把发布时间从周四提前到周三,然后在香港时间 10 月 21 日晚上 10 点,把补丁发了出去。
02「不用登录就能进」,是最要命的那种
安全圈里管这类漏洞叫「未认证远程代码执行」。听起来像黑话,翻译成人话是:对方不需要账号、不需要密码、不需要你点任何东西,只要你的机器开着网页服务,他就能让你的服务器替他执行命令。
这两个漏洞各有一条路。
第一条(CVE-2026-109618)跟「上传」有关。PHP 在处理上传请求时,如果内存不够用了,它会提前退出。问题出在这个「提前」上:退出得不够干净,留下一块本该被清掉、却还能被读写的内存。攻击者只要构造一个特殊的表单请求,让服务器在「看起来没超过限制」的情况下把内存耗光,就能踩进这块内存。在 Apache 的 mod_php 这类部署方式下,这一步之后就是代码执行。
第二条(CVE-2026-109619)更隐蔽一些。PHP 的工作进程为了快,会把上一个请求的一些状态留着给下一个用。正常情况没事,但这次发现:某些状态下,这些「留着的记忆」没有被正确清理。攻击者连着发两个请求,第一个负责布置,第二个负责收割,中间那块已经被释放、却还被指着的内存,就成了入口。
03补丁发出几小时后,就有人在打了
本喵写这篇的第一版时,公开信息还是「没有确认的在野利用」。等到核第二遍,这条已经过期了。
多家安全厂商在 10 月 21 日报告了实际攻击活动:Aikido 说有在野利用,Patchstack 说确认了多起活跃的入侵事件。两家都没有公开技术细节,这个漏洞目前也还没被收进美国 CISA 的「已知被利用漏洞」目录。但那是走流程的时间问题。
从泄露到有人动手,不到 48 小时。这个速度值得单独说一句:过去习惯的节奏是「补丁发了,排期升级」;现在的节奏是,补丁和攻击几乎同时到。
04公网上的 150 万台,和那 88 万台
有个网站叫 Shodan,专门给公网上的设备做「点名」。它不入侵、只读响应头,所以能数出一个大概。
按它的统计(10 月 20 日,补丁发出的前一天),公网上有 223 万台机器在响应头里报了 PHP。其中 149.6 万台报了具体版本号,剩下 74 万台把版本藏了,占三分之一。
前后两个数放一起才看清:能拿到补丁的是四成,拿不到的是六成。这六成里,光 PHP 5.6 和 7.2 两个版本就占了三十七万台。
这些机器也不散。它们集中在几家云厂商手里:亚马逊超过二十九万台,Hostinger 十四万,阿里云八万,Hetzner 五万,DigitalOcean 四万七,OVH 三万七。共享主机上一台机器能挂几百个网站,所以按网站算,受影响的面比机器数还大。
按主机数排,盘子最大的是美国(59.3 万台)、中国(19 万台)、德国(15.4 万台)、日本(14.2 万台)、香港(6.8 万台)。这里本喵没有算各国的百分比:不同来源对「无补丁」的口径对不上,硬算会算出互相矛盾的数字。绝对数已经够说明问题了。
再换一个口径看网站。做统计的 W3Techs 说,在能被识别出服务端语言的网站里,69.4% 用 PHP;这些 PHP 网站里 64.4% 跑的是 PHP 8,剩下的 35.6% 在 PHP 7 或更早。一个数机器,一个数网站,结论指向同一个地方。

05PHP 官网自己是怎么说的
官方那份支持周期表,比任何解读都直接。规矩是:每个分支从发布起,两年「完整支持」,再加两年「只修安全问题」,四年一到就停。
| 分支 | 安全支持到 | 对今天的意义 |
|---|---|---|
| 8.2 | 2026-12-31 | 两个月后到期。这次拿到了补丁,但年底前还得再升一次。 |
| 8.3 | 2027-12-31 | 还有一年多,可以按正常节奏排期。 |
| 8.4 | 2028-12-31 | 相对从容。 |
| 8.5 | 2029-12-31 | 最新分支,生命周期最长。 |
| 8.1 及更早 | 已过期 | 不会有任何补丁。这次不会有,下次也不会有。 |
这张表藏着今天最容易被忽略的一件事:很多人以为升到 8.2.35 就安稳了。安稳是安稳,但只安稳到今年最后一天。
换句话说,今天动手升级的 8.2 用户,年底前还要再动一次。如果升级的代价很高,这一次不如直接升到 8.3 或 8.4,把下一次的时间窗口拉长。
06除了这两个洞,PHP 还常在这几个地方漏
这两个漏洞总会修掉。但本喵翻了一圈发现,公网上暴露最多的其实不是漏洞,是「本不该对外的信息」。这些东西平时不疼不痒,一旦有洞,就是给攻击者递地图。
| 暴露点 | 泄露什么 | 怎么查 |
|---|---|---|
| 版本号裸奔 | 响应头直接告诉对方 PHP/7.4.30,等于自报「我这里旧」。 | 看响应头 |
| phpinfo() 页面 | 路径、配置、扩展、数据库地址、密钥片段。有扫描报告说,暴露出来的这类页面里六成半跑在 PHP 8.0 以下。 | 访问自己站的 /phpinfo.php |
| 调试模式与错误页 | 报错时把文件路径、SQL 语句、框架版本全打出来。 | 访问一个不存在的路径 |
| 上传目录可执行 | 传上去的图片能被当脚本跑。老问题,但每年都有站中。 | 看 nginx 有没有禁 .php |
| 管理面板暴露 | phpMyAdmin、后台登录页直接对公网开放,等着被撞库。 | 从外网访问一次后台路径 |
| 老插件与老 CMS | WordPress、Drupal、Magento 的插件漏洞,补丁往往比 PHP 本体慢得多。 | 看后台更新列表 |
展开:一条能自己跑的暴露面自查(只查自己的站)
# 1 看响应头有没有自报版本
curl -sI https://你的域名/ | grep -i "x-powered-by\|server"
# 2 试几个常见的敏感路径(都应该 404)
for p in phpinfo.php info.php .env .git/config admin/ phpmyadmin/; do
printf "%-16s " "$p"
curl -s -o /dev/null -w "%{http_code}\n" "https://你的域名/$p"
done
# 3 触发一次 404,看错误页有没有吐出路径或框架版本
curl -s "https://你的域名/zzz-不存在的页面" | head -30
# 4 在服务器上查自己的 PHP 版本
php -v
这几条没有一条算「高危漏洞」。它们在渗透报告里通常只占一行,标成「信息泄露」。可一旦出现像这次这样的远程代码执行,那行信息就成了选靶子的依据:谁的版本老、谁的路径浅、谁的扩展有已知问题,一目了然。
07版本对照表:一张就够
判断自己有没有事,只需要一个版本号。低于右列的,就是需要动手的。
| 分支 | 受影响 | 安全版本 |
|---|---|---|
| PHP 8.5 | 低于 8.5.12 | 8.5.12 及以上 |
| PHP 8.4 | 低于 8.4.27 | 8.4.27 及以上 |
| PHP 8.3 | 低于 8.3.36 | 8.3.36 及以上 |
| PHP 8.2 | 低于 8.2.35 | 8.2.35 及以上 |
| PHP 8.1 及更早 | 全部版本 | 不会有补丁 |
一个实操上的小陷阱:PHP 的修复方式不是「发一个补丁文件给你打」,而是「发一个新版本」。所以你在面板里点「检查更新」看不到所谓的安全补丁,得看版本号有没有变。
08你属于哪一类,决定了今天要不要加班
第一类:自己的机器上跑着 PHP
先查版本。一条命令的事。
展开:查版本 / 升级的几条命令
# 查版本 php -v # 容器里 docker exec <容器名> php -v # Debian/Ubuntu 系,确认候选版本是否已到安全线 apt-cache policy php8.2-fpm # 升级(云厂商镜像源同步后) apt update && apt install --only-upgrade 'php8.*' systemctl reload php8.2-fpm # 升完再查一次,版本号变了才算数 php -v
用宝塔、aaPanel、cPanel 这类面板的,去面板的软件商店里直接换 PHP 版本,比自己编译省事。跑 Docker 的,把镜像 tag 换成安全版本重建容器,先确认 php -v 对了再切流量。
这里有个容易误判的地方:Debian、Ubuntu、RHEL 这类发行版有时会把安全修复回填进旧版本号里。所以看到版本号没变先别急着下结论,去查一下发行版自己的安全公告,确认这个包是不是已经带了修复。
第二类:网站托管在别人那里
你不需要知道 PHP 是什么,但你需要问对人。问题只有一句:「我们站点的 PHP 版本现在是哪个?到 8.2.35 以上了吗?」
如果对方回「已经打了补丁」,可以再追一句「能发一下 php -v 的输出吗」。这话不是刁难。按这次官方给的形式,没有单独补丁,只有版本号能证明。
第三类:只是用网站,不运维
这件事你不用动手。但如果最近收到「你的账号异常,请点此验证」这类邮件或短信,多留个心眼。老版本被攻破之后,最常见的二次利用就是拿站点去发钓鱼信息,看起来还是从你熟悉的那个域名发出来的。
09老化的基础设施,总是最后才被看见
写这篇的时候,本喵一直在想一个有点扫兴的问题:为什么总是这种时候,大家才想起来看版本号。
因为 PHP 这样的东西,它的优点是「看不见」。一个网站跑得好好的,没人会去问它底下是什么版本。它不出错、不报警、不占版面,就像一个用了十年的配电箱,安静地待在墙里。直到有一天它被写进安全公告,人们才第一次认真打量它。
这次补丁发得算干净:同一时刻、四个分支、说明清楚。真正难的从来不是发补丁,是让补丁落到那些已经没人维护的机器上。那八十八万台机器的主人,可能早就换了工作,公司可能已经注销,服务器还在机房里插着电,安静地对外提供着服务。
还有个更少被提起的角度:PHP 8.2 年底就到期。也就是说,今天这场紧急升级,对相当一部分人只是把下一次限期推后了两个月。基础设施的账不会消失,它只会在你最不想算的时候来找你。
本喵也没有答案。只是觉得,一个 9.2 分漏洞的新闻里,最该被记住的可能不是分数,而是那 59%。