PHP2Shell is the name given to two critical remote code execution flaws, CVE-2026-109618 and CVE-2026-109619, that PHP patched on 21 October 2026. Both score 9.2 on CVSS v4.0, and both can be triggered by an unauthenticated web request. If any server you deploy to runs PHP, this is a patch-today situation.
DeployHQ status: the DeployHQ Build Pipeline is already live with the patched PHP versions. The servers you deploy to are yours, though, so the steps below still apply to them.
This guide covers what is affected, which versions fix it, what to do if you can't upgrade right now, and how to roll the fix out without leaving a stale process serving traffic.
What was fixed
PHP released four patched versions:
| Branch | Patched version |
|---|---|
| 8.5 | 8.5.12 |
| 8.4 | 8.4.27 |
| 8.3 | 8.3.36 |
| 8.2 | 8.2.35 |
The two bugs, as described by BleepingComputer:
- CVE-2026-109618 — PHP can be left with corrupted memory when a request ends abnormally (out-of-memory). A chain of weaknesses turns that into code execution as the web worker's user.
- CVE-2026-109619 — a stale global state bug that allows a heap use-after-free, memory disclosure and code execution with the same privileges.
The advisories are tracked on GitHub as GHSA-w8hw-w9fx-j79w and GHSA-6wmf-4rv5-p3rp.
Are you affected?
If PHP serves web requests on your servers, assume yes. The advisory scope covers PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed. Risk is not equal across them:
- mod_php is the highest risk. The PHP team reports a demonstrated exploit where a single unauthenticated request triggers the attack before any of your application code runs.
- PHP-FPM and LiteSpeed (LSAPI): no complete exploit has been demonstrated for the memory bug, but
not demonstrated
is notsafe
. Patch them too. - CLI-only PHP (cron scripts, Composer, artisan) is outside the advisory's scope of web-serving installations.
That includes the PHP you don't think of as a PHP server: WordPress and WooCommerce stores, Drupal, Laravel apps, admin panels like phpMyAdmin, and old internal tools. If you ship a Laravel application or a WooCommerce store, the runtime on those servers is in scope.
End-of-life versions get no official patch
PHP 8.1 and older no longer receive upstream security releases. Source backports for 7.4, 8.0 and 8.1 exist, and some distributions and hosts (cPanel, for example) have shipped their own, but you shouldn't count on that. If you are on 8.1 or earlier, the fix is to upgrade to a supported branch. Note that 8.2 itself reaches end of life on 31 December 2026, so 8.3 or newer is the better target if you have a choice.
Patch first, then restart
The fix is a PHP upgrade. Two details trip people up:
php -vcan lie about what's serving traffic. The CLI binary and the FPM or Apache module are often different builds. Check the one the web server uses, for example with a smallphpinfo()page behind authentication orphp-fpm -v, then remove the page.- A package update doesn't replace running workers. Restart PHP-FPM or Apache after upgrading, or the old code stays loaded in memory.
Containers need one more step: an image built before the patch still contains the old PHP until you rebuild and redeploy it. Bump your base image tag (for example to php:8.4.27-fpm), rebuild, and ship.
If you can't patch today
PHP published stopgaps. They reduce exposure to specific attack paths and do not make an installation safe, so treat them as a bridge to the upgrade, not a substitute.
For CVE-2026-109618:
- Set
memory_limit=-1withphp_admin_valuein the FPM pool or Apache config, so applications can't override it back to a finite limit. - Set
post_max_sizeto 8M if you don't accept uploads, or 32M if you do, and keepupload_max_filesizebelow it. - Enforce request size, field count and multipart limits at the web server or proxy, and block multipart requests entirely if your app doesn't use them.
- Use a container or cgroup memory limit. Don't use
RLIMIT_ASorRLIMIT_DATA.
For CVE-2026-109619:
- Set
session.upload_progress.enabled=0inphp.ini, the FPM pool or server config (not viaini_set()or.user.ini). - On PHP 8.5, also set
fatal_error_backtraces=0. - Restart every worker afterwards.
Hiding errors with error_reporting, display_errors or the @ operator does nothing for either bug.
Rolling the patch out with DeployHQ
Here is where deployment tooling matters, and where a common misconception lives: deploying your code doesn't patch your server's PHP. A deployment copies your application files; the PHP runtime on the server is a separate thing you update with your OS package manager, your hosting control panel or your base image.
The DeployHQ Build Pipeline is already live with the patched PHP versions, but that doesn't reach your own servers or images. If you're setting up a PHP pipeline from scratch, see our walkthrough on deploying a PHP site with Composer, Laravel or WordPress.
What a deployment workflow does give you:
- Containerised apps and build steps: change the base image tag in your Dockerfile (or bump the PHP version in your build pipeline), commit, and let an automatic deployment from Git push the rebuilt image out instead of waiting for someone to remember.
- Servers you manage over SSH: use post-deployment commands to reload PHP-FPM once the new release is in place, so workers pick up the patched runtime and your fresh code together. See the DeployHQ support docs for SSH commands.
- Config-based stopgaps: if you manage pool or ini files in your repository, the mitigations above can ship as a normal commit through your usual zero downtime deployments flow.
- Safety net: if an upgrade breaks something, one-click rollback gets your previous release back while you investigate.
Patching the host itself is still your job, or your host's. On managed platforms (App Platform, Cloudways, Laravel Cloud and similar) check whether the provider has already rolled out the patched build. Laravel Cloud, for instance, patched in place, while servers provisioned with Laravel Forge needed a manual PHP update. If you run Forge for provisioning and DeployHQ for releases, our post on using DeployHQ and Forge together explains which tool owns which step.
Is it being exploited?
Reports differ. BleepingComputer cites Cloudflare as observing early attack attempts against both vulnerabilities before the patches landed, and the PHP team describes a demonstrated exploit for mod_php. Other trackers say mass exploitation was unconfirmed at the time of writing. Assume the worst and act as though exploitation is underway. If you've been exposed since before 21 October, look at your web server logs for unusual multipart POSTs and at your servers for unexpected files or processes owned by the web user.
A one-day checklist
- List every server, container image and managed app that serves PHP.
- Identify each one's PHP version as seen by the web server, not the CLI.
- Upgrade to 8.5.12, 8.4.27, 8.3.36 or 8.2.35 (or a vendor backport you trust).
- Restart PHP-FPM, Apache or your container workers.
- Rebuild and redeploy images built before 21 October.
- For anything still on 8.1 or earlier: apply the stopgaps today and schedule the upgrade this week.
- Review logs for the period before you patched.
FAQ
Does patching require a code change in my application? Usually not. These are fixes in the PHP engine, so upgrading within your branch (for example 8.3.35 to 8.3.36) is a patch-level change. Moving off an end-of-life branch is a bigger step and needs testing.
I only use WordPress. Do I need to do anything? Yes, but it's your host or server that needs the PHP update, not a WordPress plugin. Check your hosting dashboard or ask your provider which PHP build you're on and whether the patch has been applied.
Are the memory_limit and session.upload_progress settings enough?
No. PHP is explicit that they only close specific attack paths. Use them to buy time, then upgrade.
Is the PHP CLI affected? The advisory covers installations serving web requests. CLI-only usage such as cron jobs and Composer is outside that scope, but patch it anyway so your environments stay consistent.
Will deploying my app update PHP on the server? No. Deployments change your application files. Update the runtime through your OS, host or base image, then restart workers.
Is the DeployHQ Build Pipeline patched? Yes. The Build Pipeline is already live with the patched PHP versions. That doesn't cover your own servers, so patch those separately using the steps above.
Patch, restart, verify
Check which PHP your web server actually runs, upgrade to a fixed release, and restart the workers. If you ship PHP apps from Git and want the patch-and-reload steps to be repeatable rather than a late-night SSH session, start a free DeployHQ account and automate it.
Questions about rolling this out? Email support@deployhq.com or find us on X at @deployhq.