PSA: update PHP today

By

PHP security fixes are available. Update now, check the fixed versions, and use these temporary mitigations only while waiting for patched packages.

~~~

If you run a PHP website, make time to update PHP today.

The fixes are available. PHP released its security update on October 21, 2026. Install the patched release for your branch:

PHP branchFixed release
PHP 8.28.2.35
PHP 8.38.3.36
PHP 8.48.4.27
PHP 8.58.5.12

Your Linux distribution may backport the fixes without adopting these exact upstream version numbers. Check its security advisory and package revision.

This concerns the PHP runtime underneath your application. Updating WordPress plugins or running composer update does not update that runtime.

What’s happening?

The vulnerabilities, CVE-2026-109618 and CVE-2026-109619, can allow an attacker to run code on your server without logging in. Both carry a CVSS v4.0 score of 9.2 out of 10.

PHP’s warning covers installations serving web requests, including PHP-FPM, Apache’s PHP module, CGI, FrankenPHP, and LiteSpeed. Some confirmed exploit paths run before application code, so a login screen or a framework maintenance page doesn’t protect the runtime.

The PHP Foundation confirms that remote code execution was demonstrated before application code on mod_php with default settings, and through application-level code paths on PHP-FPM.

If you run Laravel, WordPress, Drupal, or another PHP application, check the PHP installation that serves it. Include old sites and admin tools you rarely open.

The core issue

A PHP worker stays up and handles many requests. When a request hits a fatal error, including running out of memory, PHP does not return from the function it was in. It jumps out with longjmp(). PHP calls that jump a bailout.

The jump skips the cleanup of the work in progress. The request’s internal data can be only half built, or the worker can still hold a pointer into memory that request already freed. Shutdown, or the next request on that same worker, then treats the leftover as real data. That is how the worker can be made to run an attacker’s code.

The changelog line for the fix is “Avoid state corruption via bailout.” The two CVE numbers are two ways into it.

Out of memory

CVE-2026-109618 is the case where the jump happens while PHP is still setting the request up. Shutdown then reads that unfinished memory. On Apache with mod_php, a demonstrated case does this before any of your application code runs.

The patched releases store the out-of-memory error and raise it at the next safe point in the virtual machine, once the normal memory_limit is crossed. A second, higher limit kills the process with _exit() and skips that cleanup.

Leftover pointers

CVE-2026-109619 is the pointer left behind. The worker keeps global fields for errors, sessions and similar state, and those fields point into the current request’s memory. A bailout can free that memory and leave the fields in place. The next request on the same worker can use them before normal startup replaces them. The patch clears that state when the request ends.

How a PHP bailout leaves bad stateA fatal error or out-of-memory condition jumps out of the current work. One path leaves request data half built, and shutdown reads it. The other leaves a worker pointer at freed memory, and the next request on that worker reads it.Out of memory orfatal errorBailout jumps outRequest data halfbuiltPointer left atfreed memoryShutdown reads itNext request on thesame worker reads it

Why the fix took time

The Foundation says early signs of the out-of-memory problem emerged in 2024. Compatibility concerns, limited resources, and difficulty agreeing on a fix delayed the work. Reports demonstrating remote code execution made it the team’s top security priority in August 2026. The team is changing its decision process to resolve similar problems faster.

Leaked CVE IDs prompted PHP to move the release from October 22 to October 21. At disclosure, the security team had found no working exploits among the public PoCs it inspected. That observation applies to those PoCs at that time; it doesn’t establish whether servers have since been compromised. The Foundation’s account covers the disclosure timeline and funding needs.

If you use Laravel Cloud, Forge, or Vapor

Laravel announced these platform actions. Check its latest platform notices for confirmation that your applications have been patched:

PlatformWhat you need to do
Laravel CloudLaravel announced automatic patching, with no manual action required. Confirm completion through its platform notices.
Laravel ForgeManually update your server’s PHP version through the Forge dashboard as soon as the patched package is available. Laravel says to power down the server if you cannot update it.
Laravel VaporLaravel announced automatic redeployment for PHP 8 applications. Its instructions tell PHP 7 users to upgrade to PHP 8. Check that your deployment has received the fix.

For Forge, Laravel confirmed the dashboard path: open your server, then Runtime → Versions, open the three-dot menu, and choose the update action for your PHP version.

If you manage the server yourself

Check your distribution or PHP package provider’s security advisory and install its fixed packages. If you deploy containers, rebuild with a patched PHP base image and replace the running containers. Static builds such as FrankenPHP bundle their own PHP runtime, so updating the system’s PHP package won’t update that binary.

Restart the PHP services and long-running workers that need it so they load the updated runtime. Then test the site and check the PHP version serving web requests. php -v checks your command-line PHP, which can differ from the PHP used by your web server.

Apply the PHP security updateIdentify each PHP deployment, obtain the patched runtime from its provider, restart or redeploy it, and verify the running application. Confirm completion when a managed platform patches automatically.Your platformautomaticallyYouFind your PHPdeploymentsWho applies thepatch?Watch for patchconfirmationInstall fixedpackages or rebuildimageRestart services orredeployVerify running PHPand test the site

If you use shared or managed hosting, ask your provider whether the fix has been applied to your site’s PHP runtime. Check each site if your account uses several PHP versions.

PHP currently supports branches 8.2 through 8.5. PHP 8.1 and older are end of life upstream. Your distribution may still maintain its own packages, as Ubuntu does for PHP 8.1 below. The PHP security team has exceptionally supplied minimal source backports for 7.4, 8.0, and 8.1; these are not a return to normal upstream support or ready-made packages. Ask your vendor about a maintained fix or upgrade to a supported branch.

Ubuntu and Debian fixes are available

Ubuntu’s security notice USN-8948-1 lists these fixed package revisions:

Ubuntu releaseFixed PHP package revision
22.04 LTS8.1.2-1ubuntu2.28
24.04 LTS8.3.6-0ubuntu0.24.04.13
26.04 LTS8.5.4-0ubuntu1.5
26.108.5.9-0ubuntu2.1

These apply to Ubuntu’s official packages. If you use a third-party PHP repository, check that provider’s advisory and fixed revisions.

An older upstream version number can still contain the fix. Ubuntu backports patches, so compare the complete package revision with its notice. Ubuntu 22.04’s patched PHP 8.1 package is one example of distribution maintenance continuing after upstream support ends.

Debian’s trackers for CVE-2026-109618 and CVE-2026-109619 list these fixed security packages:

Debian releaseFixed PHP package revision
Debian 12 (Bookworm)8.2.35-1~deb12u1
Debian 13 (Trixie)8.4.27-1~deb13u1

Install the security updates for your release, then restart the services using PHP and verify the running site as described above.

If you use Cloudflare

Cloudflare has deployed PHP-specific WAF protections, including on Free plans. Free users receive the rules automatically. On paid plans, confirm that the Cloudflare Managed Ruleset is deployed in Block mode.

Cloudflare reports attack attempts, including changes to payloads aimed at bypassing its filtering. That establishes observed attack traffic, without showing that those attempts successfully compromised servers.

Some of the new protections inspect a request together with the origin’s response. They can block a matching response before it reaches the attacker. That means some detection happens after PHP has processed a request.

Keep the WAF enabled while you patch. Make sure attackers cannot reach your origin directly and bypass Cloudflare. Update PHP even with these protections enabled. The linked announcement includes rule IDs and instructions for reviewing matched traffic under Security → Security Analytics → Events.

Temporary mitigations while you wait for packages

Mattias Geniar’s mitigation guide collects practical configuration examples and their limitations. PHP has now published its own advice too. These measures only reduce exposure to particular attack paths. Updating PHP is the complete fix.

If you can install a patched package now, do that first.

Disable session upload progress

The stale-state advisory recommends disabling session upload progress to block the confirmed session paths. Add this to the configuration used by your web-serving PHP runtime:

session.upload_progress.enabled = 0

On PHP 8.5, also disable fatal error backtraces:

fatal_error_backtraces = 0

Use php.ini, an FPM pool, or server configuration applied before request parsing. Restart every PHP worker and check the effective settings. Application-level ini_set() and FPM .user.ini are too late for this purpose.

These settings leave other paths open. Also remove obsolete or invalid per-request PHP settings that generate warnings. Hiding those warnings with display_errors or error_reporting does not remove the underlying problem.

Reduce the request and memory attack surface

The out-of-memory advisory recommends blocking multipart requests at the frontend when the application doesn’t need them. This must happen before PHP parses the body. Check your forms first: a multipart block can break legitimate requests, including uploads.

PHP also recommends administratively enforcing memory_limit=-1 as an incomplete workaround. That removes PHP’s per-request memory cap, so a request can consume the server’s memory. A container or cgroup boundary can limit resource exhaustion, but may kill multiple workers and still cannot eliminate vulnerable allocation failures. Do not substitute RLIMIT_AS or RLIMIT_DATA, which can cause that failure.

Keep request limits conservative and enforce decoded body size at the frontend too. PHP’s guidance suggests post_max_size=8M without uploads, or 32M with uploads, keeping upload_max_filesize below it. A small post_max_size alone doesn’t cover every parsing path.

Don’t copy memory-limit changes into production without checking what they do to your application and host. The configuration details and remaining limitations are in the linked advisory.

Take the site offline safely if you cannot patch

CERT-EU recommends considering isolation when you cannot patch promptly.

Mattias highlights an easy mistake here: removing the PHP handler can make a web server serve your PHP source as plain text, potentially exposing secrets. Block access, stop the web server, or have it return a static maintenance response without passing requests to PHP. Verify the result from outside.

Keep temporary protections until the updated runtime is running and you have checked the site. Then review the temporary settings: restore an appropriate PHP memory cap if you removed it, and test any uploads before lifting a multipart block. If you suspect a break-in, isolate the server and preserve the logs. Patching PHP does not remove files or other changes an attacker may already have left behind.

Tagged: PHP · All topics

Want me to talk about your product? You can sponsor this site.

~~~

Related posts about php: