PHP 出大事:CVE‑2026‑109618 / CVE‑2026‑109619,俩 RCE 漏洞搁这儿摆着呢

2026-10-22/码农修仙/共2760字/暂无评论

昨晚上是 php 攻城狮们最难熬的一晚了吧。

没什么故弄玄虚吓唬人的,就是实打实踩上一个安全大坑。

CVSS 9.2 分,预认证远程代码执行。

用不着偷你的账号密码,攻击者随便扔一段精心捏出来的 HTTP 请求,

运气凑齐了,服务器就归人家串门了。

这年头做后端,PHP 这老伙计,平日里勤勤恳恳闷头干活,冷不丁就给你扔出来俩内核漏洞。

别上来就骂业务代码写得烂,这回不赖业务,是底层内存耍了脾气。

说直白点,内存玩脱了,指针到处瞎指,内部状态搅得一塌糊涂,外人借着这个空子,就能在机器上跑代码。

两个窟窿,CVE-2026-109618、CVE-2026-109619,各是各的毛病,别混作一团看。

CVE-2026-109618

内存撑爆 OOM 的那一刻,PHP 图省事,干脆一个跳转直接跑路,该收拾的内存,半点儿没收拾。

攻击者构造个畸形的 multipart 请求,故意把内存给干崩,后面程序接着去碰一堆脏乎乎的内存,机会就这么送出去了。

这里得把话说透:

Apache mod_php 属于最倒霉的那拨,用不着你业务代码配合,光解析请求就能被攻破。

FrankenPHP 和它是一路货色,风险一点不比前者小。

FPM 看着稍微体面点,但也不是保险柜,别觉得用了 FPM 就可以高枕无忧睡大觉。

CVE-2026-109619

说白了就是野指针瞎闯祸。

PHP 的 worker 常驻内存过日子,撞上致命错误,拔腿就跑,把该重置的全局状态忘得一干二净。

上一个请求已经释放干净的内存,指针还堂而皇之留在全局里头。

新请求刚起个头,初始化还没干完,转头就去读那块早就作废的内存。

use-after-free,RCE 就这么来了。

目前实打实地踩出来一条路,根源就在 session.upload_progress。

官方说得也算实在:

别幻想改几行配置就能把窟窿堵死,升级才是正经过日子的办法。调参数顶多降低挨揍的概率,不等于就安全了。

受祸害的版本,从 PHP 5.4 一路蔓延到 8.2.34 / 8.3.35 / 8.4.26 / 8.5.11。

修好的版本:8.2.35、8.3.36、8.4.27、8.5.12。

8.1 以及往下的老版本,早就没人维护了,补丁是不会有了,该挪窝就趁早挪窝。

网上传得满天飞的 php2shell-poc 的 A/B/C 三条利用链,跟眼下这两个 CVE 压根不是一回事。

别拿这个 POC 去测自己修没修好,纯属白费功夫,补丁压根就没碰那几块逻辑。

也就个别缓解手段碰巧撞在了一起,仅此而已。

拿我自己 docker 跑的 frankenphp 举例子,省事的法子,就改 Dockerfile 最顶上那一行。

FROM dunglas/frankenphp:1.13.2

完事敲一条命令:

docker compose up -d --build

其余各位,把 PHP 升到打过补丁的版本就完事。

至于 8.1 往下的老版本,官方摊手直接不给补丁了,说起来也挺无奈。

网上能搜到的各路偏方,无非改改 php.ini 参数临时挡一挡,给你挤出点时间踏踏实实做升级。

php.ini 中修改项,务必去 phpinfo() 页面确认确实生效:

session.upload_progress.enabled = 0
; PHP8.5 才需要下面这行
fatal_error_backtraces = 0
memory_limit = -1
post_max_size = 8M
max_file_uploads = 20
max_input_nesting_level = 32
max_input_vars = 1000

Apache,丢进 httpd.conf 或者 vhosts.conf

LimitRequestBody 8388608
LimitRequestFields 50
LimitRequestFieldSize 8190

Nginx,贴到 server{} 配置块里面

client_max_body_size 8m;
large_client_header_buffers 4 8k;

分环境掂量掂量优先级

  1. Apache mod_php / FrankenPHP:头等大事。
    优先升级。
    实在暂时动不了版本,全套缓解配置先怼上去。
    长远眼光看,尽量往 FPM 那边靠。
  2. PHP-FPM / LSAPI:抓紧升级。实在升不动,全套缓解配置一个别落下。
  3. 8.1 以及更早 EOL 老版本:
    没有官方补丁,早琢磨迁移,别硬扛。

几件别干的傻事

  • 只做 reload,不完整重启进程,旧 worker 还在跑,等于啥也没干。
  • 指望代码 ini_set() 或者 .user.ini 关掉 upload_progress,不好使,白忙活。
  • 以为把错误显示一关,调调 error_reporting 就能防御。漏洞根本不需要报错输出,纯属自我安慰。
  • 图省事拿 RLIMIT_AS 做内存限制,反倒帮攻击者创造条件。
  • 光改个 post_max_size 就觉得万事大吉,人家有法子绕过去,web 层的限制一样不能少。
  • 拿网上 php2shell 的 POC 检验漏洞修复,测不出真结果,别瞎折腾。

收尾唠两句

这回是 PHP 内核根子上出的岔子,不是普通业务写崩的小 bug。

跑 mod_php、FrankenPHP 的朋友,多上点心。最踏实的路子摆在明面上:PHP 升级到修复版本,FrankenPHP 更到 1.13.2。

容器环境改个镜像标签,docker compose up -d --build,一步到位。

Nginx、Apache、php.ini 的这些配置,只能当个临时缓冲过渡,别拿权宜之计,当长久过日子的办法。

正文完

AI课代表总结

呜呜吓死宝宝了!看到预认证 RCE 我直接垂死病中惊坐起,赶紧跑去改 Dockerfile 重新 build~ 老版本可千万别硬扛,大家都要听博主的话乖乖升级,拒绝当背锅侠!打完补丁终于能安心睡美容觉啦,博主总结得太到位了,给你贴贴哦!

暂无评论