The only complete fix for CVE-2026-109618 and CVE-2026-109619, the two critical PHP remote code execution bugs known as PHP2Shell and patched on 21 October 2026, is updating to PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35. The PHP project says so in its advisory and this post does not argue with it. But on release day many servers cannot take the update: the distribution package is still building, the control panel has not shipped its rebuild, the application is pinned to PHP 7.4 or 8.1, or the change window is tomorrow. This post covers what you can do in the meantime: the interim settings the PHP security team published, the routes that get a real fix onto an end-of-life version, and the isolation and migration options when neither applies. Read the explainer for the background and the patching guide for the update itself.
What an interim measure is, and is not
Everything in the first half of this post narrows a known attack path. Nothing in it fixes the underlying bugs, and the PHP advisory is explicit that these measures "reduce exposure to specific attack paths but do not make an installation safe". So the order of operations is: apply the interim settings in the next hour, get a real fix on in the next day, and treat the time in between as exposure to be minimised rather than a problem solved. If the server hosts something that matters and no fix route exists for it, taking it offline or putting it behind an allowlist is a legitimate answer, and this post says when.
The interim settings from the PHP advisory
The php.net advisory lists a short set of configuration changes, each tied to one of the two bugs. Apply them in a place the application cannot override (php_admin_value and php_admin_flag in the PHP-FPM pool or the Apache configuration, or the system php.ini), restart every worker, and check that no .htaccess, .user.ini or application bootstrap puts the old value back. Settings applied per request through ini_set() or .user.ini are too late for this purpose, and the advisory says not to rely on them.
| Setting | Covers | What the advisory says | Side effect |
|---|---|---|---|
memory_limit = -1 | CVE-2026-109618 | Removes the controllable memory-limit failure. Incomplete: an underlying allocation failure can still reach the vulnerable path. Pair it with a container or cgroup memory limit as the availability boundary, preferably one that kills only the affected worker. | A single request can use all available memory unless the cgroup limit is in place. |
post_max_size = 8M (32M if uploads are needed), upload_max_filesize below it | CVE-2026-109618 | Keeps request bodies small. Also enforce decoded request size, input field count, multipart part count, header count and nesting depth at the web server or proxy, including for requests without a usable Content-Length. | Large uploads fail until the limits are raised again. |
session.upload_progress.enabled = 0 | CVE-2026-109619 | Blocks the confirmed session paths but not other variants. Set it in php.ini, the FPM pool or server configuration and restart every worker. | Session-based upload progress bars stop working. Almost nothing modern uses them, and the PHP team suggests leaving this off after patching too. |
fatal_error_backtraces = 0 (PHP 8.5 only) | CVE-2026-109619 | Blocks the confirmed fatal backtrace path only. | Fatal errors lose their stack traces in the log until re-enabled. |
| Remove deprecated or invalid per-request INI settings | CVE-2026-109619 | Settings applied per request that emit a diagnostic before initialisation are one of the identified triggers. Hiding diagnostics with error_reporting, display_errors or @ does not help; remove the setting instead, or move it to startup configuration. | None, beyond reviewing .htaccess files and proxy-passed PHP_VALUE parameters. |
| Fix attacker-reachable fatal errors and timeouts | CVE-2026-109619 | Includes failures in callbacks, upload or import processing and cleanup. The advisory recommends enabling log_errors with a working error_log in a test environment and reviewing for pre-script warnings, cleanup diagnostics, fatal errors and timeouts. | An application fix, not a configuration switch; takes time. |
Two things the advisory says explicitly not to do: do not use RLIMIT_AS or RLIMIT_DATA as the memory boundary, because they cause the very allocation failure the first bug needs, and do not treat any of these as a reason to delay the update. The first and second GitHub advisories carry the full remediation notes, including the suggestion of pm.max_requests = 1 on PHP-FPM where performance allows it, so that no state carries from one request to the next.
Reduce what reaches PHP at the edge
The interim settings work on what PHP does with a request. The other lever is what reaches PHP in the first place, and for many sites that is the stronger one during the gap.
- Reject multipart form bodies where the application does not use them. The PHP advisory recommends blocking multipart requests at the frontend for applications without file uploads, since the confirmed paths run through multipart parsing. A brochure site, an API that takes JSON, or a WordPress site where only logged-in editors upload media can usually do this with a single web server or WAF rule, keeping an allowlist for the specific upload endpoints that need it. Expect every upload form outside the allowlist to break until the rule is removed.
- Go read-only if you can. If the site works with GET and HEAD alone for a day, refusing other methods at the web server removes the request bodies the known exploits rely on. Logins, forms and checkouts stop working, so this is for content sites, not shops.
- Put the WAF in front and lock the origin. Cloudflare enabled emergency managed rules for the known exploit pattern on every plan including Free, Bunny Shield shipped a matching rule, Imunify360 carries one from ruleset 8.83, and the OWASP Core Rule Set catches part of it. All of them only help for traffic that actually passes through them, so restrict the origin to the provider's IP ranges while you rely on this, and remember that a signature matches one known pattern, not the bug.
- Allowlist or take offline. An internal tool, a staging site, a client portal with a known user base: restrict access to known IP ranges or a VPN at the firewall until the update is in. For anything exposed to the public with no fix route at all (PHP 7.3 and older, Debian 11 without ELTS), serving a static maintenance page from the web server and stopping PHP is a reasonable decision for a day or two. Do not just disable the PHP handler and leave the files in place: Apache and nginx then serve the source code as plain text.
Limit what a successful exploit can do
None of these prevent exploitation. They turn "code execution as the web user" into something less useful to an attacker and easier to notice, which is worth an hour on a server you cannot patch.
- One site, one user, one pool. Separate PHP-FPM pools running as separate system users mean a compromised site cannot read the next site's configuration. On cPanel servers CloudLinux CageFS gives the same isolation per account (how CageFS works).
- Disable the process-spawning functions in
disable_functionswhere the application does not need them (exec,shell_exec,system,passthru,proc_open,popen). Many applications never call them; check before you add them for one that does, such as a backup plugin that shells out to a database client. - Confine the worker with AppArmor or SELinux so that the PHP process cannot execute binaries or write outside the paths it needs. Both distributions ship profiles you can start from.
- Egress filtering at the firewall, so the web user cannot open outbound connections except to the services the application uses. Most post-exploitation activity needs to fetch something or call home.
- Watch the logs. Turn
log_errorson with a workingerror_log, and alert on fatal errors, memory exhaustion messages and unexpected child processes of PHP workers. A spike in "Allowed memory size exhausted" entries from one client is the kind of thing worth looking at now rather than next week.
Routes to a real fix on an end-of-life version
Interim settings are for the hours before a package arrives. For PHP 8.1, 8.0 and 7.4, where no package will ever arrive from php.net, there are four routes that put the actual fix into the binary. Pick the first one that applies to you.
| Route | Who it is for | How | Caveat |
|---|---|---|---|
| Distribution backport | Ubuntu 22.04 (php8.1), RHEL 8 and 9 module streams, Debian 12 | Normal package update once the vendor publishes it; verify with the changelog, not php -v | Timing is the vendor's. Ubuntu 22.04's build was staged on release day; Red Hat's errata were still pending. |
| Extended support subscriptions | Ubuntu 20.04 and 18.04 (Ubuntu Pro ESM), Debian 11 (Freexian ELTS) | Attach the subscription, then pro fix CVE-2026-109618 or the ELTS repository update | Depends on the vendor actually backporting; Ubuntu Pro has a free tier for up to five machines. |
| CloudLinux HardenedPHP | cPanel and other panel servers on CloudLinux with accounts pinned to 7.x, 8.0 or 8.1 | dnf update 'alt-php*' once the builds are published; CloudLinux said they were in preparation | Only covers alt-php versions, not EasyApache's native packages, which cPanel updates separately. |
| Official source backport branches | Anyone building PHP from source, or without an LTS vendor | Build PHP-7.4-CVE-2026-109618-109619, PHP-8.0-… or PHP-8.1-… from the php-src repository with your existing configure options (steps in the patching guide) | Contains these two fixes and nothing else. Every other vulnerability fixed since that version's end of life remains, and the branch will not be maintained. |
A fifth route is to stop needing one: move the application to a supported version. That is a project rather than an emergency change, but it is a smaller project than it used to be. PHPCompatibility for PHP_CodeSniffer lists the breaking changes in your code, Rector rewrites most of them automatically, and the PHP 7 to 8 upgrade post covers what to test. PHP 8.2 reaches end of life on 31 December 2026, so anything landing on 8.2 now should plan to be on 8.3 or 8.4 within the quarter.
If you were exposed, assume you may have been hit
Exploitation attempts were visible within hours of the release, and the chain had been circulating as a leaked tool the day before. A server that was reachable, unpatched and running Apache with mod_php for the afternoon of 21 October should be reviewed, not just updated. That review looks for PHP files modified recently in the document roots, scheduled jobs and startup entries belonging to the web user, processes and outbound connections owned by that user that you cannot account for, and new administrator accounts in the application. If anything turns up, treat the server as compromised: rotate the credentials it held, including database passwords, API keys and anything in .env files, and restore from a backup taken before the exposure window rather than cleaning in place. A back door placed before the patch keeps working after it, which is why patching alone does not close an incident.
When the real fix lands
Interim settings have side effects, so undo them deliberately once every PHP behind them is patched and restarted. Put a real memory_limit back, since the patched engine handles exhaustion safely and an unlimited setting leaves you open to plain resource abuse. Remove the edge rules that block uploads or write methods. Keep session.upload_progress.enabled off unless something needs it, keep the per-site isolation and the egress filtering, and keep the automatic security updates you turned on today. The patching guide has the verification steps that confirm the update is actually serving requests.
And if the honest answer is that nobody on the team has time to do this for every server, that is a staffing problem with a known solution: a host whose service includes the patching. On MassiveGRID's managed cPanel hosting the platform updates, the Imunify360 WAF and the CloudLinux isolation are part of the product, and a support plan extends the same patch management to your own cloud servers.
Frequently Asked Questions
Does setting memory_limit to -1 make my server safe from CVE-2026-109618?
No. It removes the easiest way to trigger the vulnerable path, which is the PHP memory limit, but the advisory notes that an underlying allocation failure can still reach it. It also removes a safety limit, so pair it with a container or cgroup memory boundary, and treat it as a stopgap until the package update is installed.
Is disabling session.upload_progress.enabled enough for CVE-2026-109619?
It blocks the confirmed session path, which is the one validated on both mod_php and PHP-FPM, but not other variants of the stale-state bug. On PHP 8.5 you also need fatal_error_backtraces=0, and on every version you should remove per-request INI settings that emit warnings. Update as soon as the package is available.
Will a WAF or Cloudflare protect an unpatched server?
Only for traffic that passes through it, and only against the known exploit pattern. Cloudflare, Bunny Shield, Imunify360 and the OWASP Core Rule Set shipped matching rules on release day. If the origin accepts direct connections, the rule is bypassed; if the exploit changes, the signature misses. Use it as a layer during the gap, not as the fix.
We cannot block multipart requests because the site has uploads. What then?
Allowlist the specific upload paths at the web server and block multipart everywhere else, keep post_max_size and upload_max_filesize as low as the uploads allow, and put the upload endpoints behind authentication where they are not already. The allowlisted endpoints remain exposed until the update is in, so prioritise that server in the patch queue.
Is PHP 7.4 with the backport branch safe to keep running?
It is safe from these two bugs and from nothing else fixed since November 2022. The PHP security team published the branch to help people who build from source get through this incident, not to extend 7.4. Use it to buy the time a migration needs, and treat the migration as the actual fix.
Should I take the site offline?
If it is publicly reachable, runs a version with no fix route at all, and handles anything you would not want an attacker to have, yes, for the day or two it takes to arrange one. Serve a static maintenance page from the web server and stop the PHP service. Do not simply remove the PHP handler, because the web server then serves your source files as text.
A platform where the patching is someone else’s job
MassiveGRID managed cPanel hosting runs on a high-availability cluster with CloudLinux account isolation, Imunify360 web application firewall and automated patch management, in New York, London, Frankfurt and Singapore. Advisories like PHP2Shell are handled by our engineers, and your sites stay up while they do it.
Explore Managed cPanel HostingFurther Reading
- php.net: Security advisory, including the "if you cannot update immediately" section this post summarises
- GitHub advisory GHSA-w8hw-w9fx-j79w: CVE-2026-109618 remediation notes
- GitHub advisory GHSA-6wmf-4rv5-p3rp: CVE-2026-109619 remediation and audit notes
- GitHub: PHP-7.4-CVE-2026-109618-109619 source backport branch
- Canonical: Ubuntu Pro and Expanded Security Maintenance
- Freexian: Debian Extended LTS
- Mattias Geniar: early mitigation steps with web server configuration examples
- MassiveGRID: PHP2Shell explained, the vulnerabilities and who is exposed
- MassiveGRID: how to patch PHP on every platform