emin@budak: ~/blog — zsh

emin@budak ~/blog % cat php-security-release-critical-rces.md

PHP Security Release: Patch the Critical RCEs

PHP security release architecture showing a patched request path

The October 21 PHP security release deserves an emergency change window. The PHP security release fixes two critical flaws, CVE-2026-109618 and CVE-2026-109619, that can permit unauthenticated remote code execution before an application gets a chance to authenticate anyone. That makes this a runtime patch, not a framework patch.

PHP published 8.2.35, 8.3.36, 8.4.27, and 8.5.12 on October 21. The PHP advisory names PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP, and LiteSpeed among the affected ways to serve requests. The advice is unusually blunt: there are no complete mitigations. Upgrade.

What changed in the PHP security release?

The two bugs sit below ordinary application code, in runtime handling of request state and failures. CVE-2026-109618 concerns an out-of-memory bailout that can interrupt PHP while internal request data is only partly initialized. Cleanup can then treat invalid data as valid. CVE-2026-109619 concerns request-owned state that outlives the memory backing it, so a later request handled by the same worker can reach stale state before normal initialization resets it.

The NVD record for CVE-2026-109618 describes the longjmp-based OOM path. The NVD record for CVE-2026-109619 describes global state that can temporarily point into request memory. Those are implementation details, but the operational conclusion is simpler: a web request can exercise runtime machinery before routing, middleware, login checks, or an application firewall rule has meaningfully helped.

The PHP ChangeLog lists both fixes under Core as protections against state corruption via bailout. That is a useful detail. This is not a bug in a popular package that can be removed from one application. It is in the interpreter process serving the request.

Who is exposed to these PHP RCEs?

Any internet-facing PHP installation that accepts web requests on a vulnerable build should be treated as exposed. PHP identifies the highest demonstrated risk as mod_php, where an unauthenticated request can trigger the attack before application code starts. That does not create a safe harbor for FPM. FPM and other worker-based deployments are explicitly in scope, and the stale-state bug is particularly relevant to a process that handles more than one request.

PHP security release diagram of web request exposure and worker isolation
A public request reaches the runtime before application controls. The version change belongs at that boundary.

Exposure also includes software that embeds or ships PHP rather than using the operating system package. PHP calls out FrankenPHP, and the practical category is broader: container images, platform buildpacks, control-panel PHP trees, local stacks, and custom source builds. A successful operating-system package update does not repair a binary copied into an image or bundled by another product.

The right inventory question is not, “Which sites run PHP?” It is, “Which deployed executables can parse an untrusted HTTP request?” Include every architecture and every image digest. That distinction avoids a common failed response: updating the host while leaving the old runtime in a container registry or an application-specific binary directory.

Which versions should be deployed?

Deploy the current fixed patch release on the branch already in use: 8.2.35, 8.3.36, 8.4.27, or 8.5.12. PHP announced all four as security releases on October 21, and the PHP 8 ChangeLog records the bailout state-corruption fix for the maintained branches. Restart or recreate every relevant runtime worker after the package or image change. A new package on disk does not replace a live FPM pool, Apache process, or container.

Current branch Minimum fixed upstream release Deployment action
8.2 8.2.35 Upgrade, then restart web-facing workers
8.3 8.3.36 Upgrade, then restart web-facing workers
8.4 8.4.27 Upgrade, then restart web-facing workers
8.5 8.5.12 Upgrade, then restart web-facing workers

Distribution version strings may not match those upstream numbers. Debian and Ubuntu often backport the security fix into the version shipped by that release. Do not reject a package because its visible version is lower than upstream, and do not accept it because it merely has a recent date. Read the vendor security advisory and package changelog for both CVE identifiers, then verify the executable in the running deployment.

Temporary hardening can reduce one attack path, but it is not a substitute. PHP suggests disabling session upload progress and changing memory-related request limits where appropriate, while warning that only updating is a complete solution. The same deployment discipline applies to runtime security patches: patch the artifact, replace running processes, and confirm the version that receives traffic.

What should happen on PHP 8.1, 7.3, and other old branches?

PHP 8.1 and older no longer receive normal project releases. PHP supplied minimal source backports for 8.1, 8.0, and 7.4, not 7.3. Those backports exist for people who build from source or lack an LTS vendor. They are an emergency bridge, not a new supported lifecycle.

For a vendor-managed system, install the vendor fix if it explicitly covers both CVEs. Ubuntu Pro, Debian Extended LTS providers, and commercial distributions may patch an older branch without changing its upstream major or minor number. That is a legitimate security fix, but it does not make the branch current. Record the vendor advisory, apply the package update, restart the relevant service, and set a migration date.

For Ubuntu users of the Ondrej PHP PPA, a late-October package review reported patched builds for end-of-life branches from PHP 5.6 through 8.1, including 7.3. That is useful when a migration cannot happen in hours. It should not be described as an upstream PHP 7.3 release, because there is none. The same review notes that the older-branch package uses the minimal fix and disables upload progress, without gaining the newer branches hard memory limit behavior.

The decision order is clear. Prefer an official fixed release on 8.2 through 8.5. If that is impossible, use a verified distribution or PPA backport as a short bridge. If the only option is an unpatched 7.3 build, take it out of internet-facing service or move it behind an architecture that removes the direct request path while the upgrade is completed. This release is a reminder that language runtimes are part of the attack surface, even when the application code is tidy.