homelab

Two critical RCEs in PHP, and why your version number is lying to you

PHP shipped an out-of-band security release on October 21 for two critical remote code execution bugs. Both are unauthenticated. Both are CVSS 9.2. If you run anything PHP, this is tonight’s job.

And if you check your version and see something that looks ancient, don’t panic yet. The version number probably isn’t telling you what you think it is.

A network switch rack with tangled cables
Photo: cell105, CC BY 2.0.

The bugs

CVE-2026-109618 is memory corruption in out-of-memory handling. When an allocation fails, PHP can abandon a request partway through and leave invalid data behind for cleanup to walk over. Crafted multipart requests reach it.

CVE-2026-109619 is a use-after-free across requests. Internal state can keep pointing at memory that was freed when an earlier request ended, and the next request handled by that same worker can touch it.

That second one is the nastier idea. The attack doesn’t have to land inside one request. It can set something up and collect on it later, through whatever unrelated traffic the same worker happens to serve next.

Upstream fixes are in 8.2.35, 8.3.36, 8.4.27 and 8.5.12. PHP also put out limited backports for 7.4, 8.0 and 8.1.

The version trap

Here’s where people are going to get this wrong.

Run php -v on Ubuntu 24.04 and you get 8.3.6. The advisory says the fix is 8.3.36. The obvious conclusion is that you’re thirty releases behind and deeply exposed.

That conclusion is wrong, and so is the opposite one. Distributions don’t track upstream version numbers. They pick a version, freeze it, and backport security fixes into it for years. The upstream number stops moving almost immediately and tells you nothing about whether a specific fix is in there.

What actually matters is the package version. On Ubuntu that’s the bit after the dash:

apt-cache policy php8.3-fpm

For Ubuntu 24.04, these CVEs are fixed in 8.3.6-0ubuntu0.24.04.13. If you’re on .12, you’re vulnerable, and the upstream 8.3.6 part never changed. Ubuntu’s own CVE pages list the exact fixed package version per release, and that’s the number to compare against, not the one php -v prints.

Same logic on Debian, RHEL, Alma and anything else with a long-term release. Checking the upstream version on a distro package is a coin flip dressed up as diligence.

We were on .12

This site runs PHP 8.3 FPM on Ubuntu 24.04. Checked it while writing this. Installed version 8.3.6-0ubuntu0.24.04.12, candidate .13, sitting in the security repo waiting.

So the thing we keep telling other people to do, patch promptly, we hadn’t done yet, because the patch is about twelve hours old. Which is the honest version of how this usually goes. The window isn’t negligence, it’s the gap between a fix existing and someone noticing it exists.

If you can’t patch right now

The workarounds are partial. Every advisory says the same thing: updating is the only complete fix. But if you’re stuck:

  • session.upload_progress.enabled=0, then restart workers. Covers the confirmed session paths for 109619 and nothing else.
  • Set memory_limit=-1 administratively so applications can’t override it, and bound post_max_size and upload_max_filesize. Narrows the OOM path without closing it.
  • On 8.5, fatal_error_backtraces=0 covers that one path.

Don’t reach for RLIMIT_AS or RLIMIT_DATA as a substitute. They can trigger the exact allocation failure the first bug needs.

Also worth knowing: hiding errors doesn’t help. error_reporting, display_errors, log_errors and @ change what you see, not whether stale state gets accessed.

How worried to be

As of the advisories, there’s no confirmed exploitation in the wild. Researchers have a working RCE and others were reproducing it independently on the 21st, so a public exploit is expected rather than hypothetical.

That’s the same shape as the Plex chain a few days ago, where the fix had been out for ten weeks and 49,000 servers got caught inside 24 hours of the details going public. The quiet window between patch and exploit is not free time. It’s the whole budget.

PHP runs a large fraction of the internet, including most of the self-hosted things this site talks about. Go check your package version.

Sources: Rapid7’s analysis of both CVEs, Ubuntu’s security tracker with the per-release fixed versions.

Leave a comment

Your email address will not be published. Required fields are marked *