PHP2Shell: What CVE-2026-109618 and CVE-2026-109619 Mean, and How to Patch
PHP2Shell is two critical PHP flaws, CVE-2026-109618 and CVE-2026-109619, that can allow remote code execution. See who is affected and which version to install.

On 21 October 2026 the PHP project shipped emergency updates for two critical bugs now nicknamed PHP2Shell. Tracked as CVE-2026-109618 and CVE-2026-109619, both can let an unauthenticated attacker run commands on a server that is still serving web requests with a vulnerable PHP build. A login page, a patched WordPress install, or a short PHP file that only prints a message does not sit in front of the dangerous code. PHP handles the request before your application does.
Each issue is scored 9.2 on CVSS v4.0. A score of 10.0 that circulated the day before the release was wrong. The practical reading is the same either way: if a machine answers HTTP with PHP, update it, restart the workers, and then look for signs that someone arrived first.
What PHP2Shell actually is
PHP2Shell is a community name, in the same spirit as Log4Shell, for a pair of flaws in the PHP engine rather than in one blog plugin or one framework. PHP still runs a large share of the public web, and it is also packed inside appliances, control panels, network devices, and management screens where the word PHP never appears in the product brochure.
The PHP Foundation described the release as two related remote-code-execution bugs in memory handling and error handling, the parts of the engine almost every request touches. Researchers had been circling an out-of-memory problem since a 2024 audit. The full impact became clear in August 2026, and the coordinated release was pulled forward by a day after the CVE numbers leaked on 20 October.
The nickname is useful for search. The thing you install is a PHP version, not a WordPress plugin called PHP2Shell.
CVE-2026-109618 and CVE-2026-109619, side by side
Both advisories are published by the PHP project. Both are critical. They fail in different moments of a request.
CVE-2026-109618, out-of-memory corruption
Advisory: GHSA-w8hw-w9fx-j79w.
When PHP hits a memory limit it has to abandon the current request. In some moments the engine has already created internal request data that is only partly set up. If an allocation fails then, PHP can leave that data in an invalid state and later treat it as real. The confirmed result is remote code execution as the account the web worker runs under.
On Apache with mod_php, PHP showed that an unauthenticated request can reach this path before any application code runs, including under default settings. Remote code execution was also confirmed on PHP-FPM through application-level paths. That is why internet-facing mod_php deserves the first place in the queue, and why "our app checks the login" is not a control for this bug.
CVE-2026-109619, stale state on the same worker
Advisory: GHSA-6wmf-4rv5-p3rp.
A PHP worker handles many requests in one process. Some fields on that worker point at memory that belongs to a single request. That memory has to be cleared before the next request starts. A fatal error, including one caused by running out of memory, can interrupt the reset. A later diagnostic can also recreate state after cleanup has already run. The next request on the same worker may then use memory that was already freed. That class of bug is a use-after-free, CWE-416. The reporter demonstrated remote code execution against a real application on Apache with mod_php, and a worker crash was confirmed.
The two bugs are patched in the same releases. Updating once covers both.
Which PHP versions are affected
Treat every PHP build that still serves web requests as in scope until you can point at a fixed package. Upstream fixes for the supported branches landed on 21 October 2026:
| Branch | Replace it with |
|---|---|
| 8.5, before 8.5.12 | 8.5.12 |
| 8.4, before 8.4.27 | 8.4.27 |
| 8.3, before 8.3.36 | 8.3.36 |
| 8.2, before 8.2.35 | 8.2.35 |
| 8.1, 8.0, 7.4, and anything older | A vendor backport, or a move onto 8.3, 8.4, or 8.5 |
PHP 8.1 and older are outside normal upstream support. The project published minimal source backports for 7.4, 8.0, and 8.1 so distributions and long-term-support vendors can ship packages. If your host or panel has not published one, the safe path is a supported branch, not a hope that an old minor version was skipped.
PHP 8.2 itself reaches end of life on 31 December 2026. Installing 8.2.35 closes PHP2Shell and leaves you with a short runway. Plan the next jump while you are already touching the server.
The web SAPIs called out by national advisories are PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP, and LiteSpeed. CLI scripts that never accept a network request are a different exposure. The urgent inventory is anything that answers HTTP, including containers, shared hosting, and appliances you cannot patch by typing apt upgrade.
WordPress, Laravel, and "we already updated the app"
PHP2Shell is in PHP, not in WordPress core, not in a Laravel package, and not in a theme. Updating the application is still worth doing. It does not install a new PHP runtime.
Check the runtime, not the CMS version number:
- On a shell,
php -vis the first reading. Confirm it is the same binary the site uses. A server often has one PHP for cron and another for the web. - In WordPress, a site-health or server panel that prints the PHP version is the one that matters. WooCommerce, Drupal, Magento, Joomla, and custom panels are in the same position.
- In Docker, the version baked into the image is what is running. Rebuilding the image and recreating the container is the update. Restarting the old container keeps the old PHP.
- On shared hosting, you may only get a version picker. Choose a fixed release if the host offers one. If the newest choice is still 8.1 or an unpatched 8.2, open a ticket and ask which package they shipped after 21 October 2026.
Also list software that quietly embeds PHP: admin appliances, mail panels, NAS devices, and old control panels. The Dutch NCSC keeps a running product inventory in the php2shell repository. A box you cannot patch yourself should come off the public internet until the vendor ships a fix.
What to do today
The PHP release notes are blunt: there is no complete workaround. Updating is the fix. CISA's 21 October alert asks organizations to inventory every PHP install, patch internet-facing systems first, and take PHP off the network if it cannot be updated. The Canadian Centre for Cyber Security gives the same order of work.
- Find it. Web servers, CI images, composer containers, staging copies, and the old VPS that "only" hosts a landing page. Staging is on the internet more often than people think.
- Install a fixed release from the table above, or the backport your distribution published for that CVE pair. Read the package changelog so you are not installing a rebuild that predates the patch.
- Restart PHP. PHP-FPM, Apache, LiteSpeed, and any process manager that keeps workers alive. A package update that does not recycle the workers leaves the old code in memory.
- Rebuild images and pull them into production. Pin the new tag. A floating
php:8.3tag only helps after the registry has the fixed build and you have actually pulled it. - Confirm the running version with the web SAPI, not only the shell, then keep the ticket until that number matches a fixed release.
If the site cannot be patched quickly, CISA's advice is to take it offline rather than leave it up behind a hope. A web application firewall can block some known patterns and is worth enabling while you work. It is not a patch. Advice that only turns off session.upload_progress, or only raises a memory limit, does not close every path. The official advisories describe those limits clearly and still call the update the only complete mitigation.
How to tell whether someone already got in
Public proof-of-concept code showed up around disclosure. CISA said it had not observed exploitation at the time it published the alert. Other researchers reported probing attempts in the days before the patches, including reports from AWS of attempts as early as 17 October 2026. Those two statements can both be true: widespread confirmed compromise is not the same thing as nobody trying. Assume internet-facing PHP was a target, and look.
CISA's short list is the right one. Watch for PHP or web-server processes starting a shell or downloading tools. Then look for the ordinary aftermath:
- New admin users in WordPress, the database, or the server.
- PHP files you did not deploy, especially in upload folders, cache directories, and
/tmp. - Scheduled tasks and startup scripts that appeared after 17 October 2026.
- Outbound connections from the web user that the site has no reason to make.
- Memory-exhaustion errors in PHP or web-server logs around the disclosure window. They are a reason to investigate. They are not, by themselves, proof.
If the server was exposed and you cannot explain a finding, patch first so the door is shut, then rebuild from a known image rather than trying to clean a live system in place. Credentials that lived on that machine, including database passwords, API keys, and admin cookies, should be rotated after you trust the host again.
Questions people are searching
Is PHP2Shell as serious as Log4Shell?
It is the same class of headline: an unauthenticated remote-code-execution bug in a component that is everywhere, with public discussion of exploit code immediately after disclosure. The blast radius on your estate depends on how many PHP servers face the internet and how fast you can restart them. Treat the patch as emergency maintenance, then keep a list so the next PHP release is a Tuesday job instead of a night job.
Does a firewall or Cloudflare rule fix CVE-2026-109618?
It can reduce noise and block some requests before they reach PHP. The PHP project says the only complete fix is a patched release. Leave the firewall in place after you update. Do not leave the old PHP in place because the firewall is there.
Are Windows and packaged installers included?
Yes, if they run a vulnerable PHP. Official Windows builds are published with the source releases. Local tools such as XAMPP, Laragon, and DevKinsta-style stacks are safe only when the PHP folder inside them is a fixed build. A laptop that is port-forwarded for a demo is a server.
What if the host will not say which PHP they run?
Ask for the exact version string and the date of the package. "Latest" is not a version. If they cannot answer, move the site to a machine where you can read php -v from the same service that answers the website.
A simple order of work
Internet-facing mod_php first, then PHP-FPM and the other SAPIs, then containers, then anything a vendor has to patch for you. One fixed version number, a restarted worker, and a quick look through the logs will do more than a weekend of partial config tweaks.
If you would rather have someone read the versions, apply the update, and check the box for signs of a visitor, send the host and the PHP version you can already see. The useful first message is the output of php -v and whether the site is on Apache, nginx with PHP-FPM, or a panel.


