PHP2Shell is the name for CVE-2026-109618 and CVE-2026-109619, two critical flaws in the PHP runtime itself that can allow unauthenticated remote code execution. Any PHP install that serves web requests is in scope, with Apache mod_php at highest risk. Upgrade to PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35, then restart every worker.
These are not bugs in WordPress, Laravel or a plugin. They sit in the engine that runs all of them, which is why national agencies told organisations to patch at once or take sites offline. This post covers what the two flaws are, how the details leaked early, which setups are exposed, what the partial workarounds do and do not do, and how to check what you are running.
What happened
The PHP security team had planned a coordinated release. Details escaped a day early, the release was pulled forward, and several European bodies took public sites offline as a precaution while they waited.
| When (21 Oct unless noted) | What | Source |
|---|---|---|
| 20 Oct, morning | A Hacker News post claims two critical PHP RCE flaws are about to be disclosed. It is taken down, but screenshots spread. | Huntress |
| 20 Oct | watchTowr publishes an FAQ and says it reproduced CVE-2026-109618. Its CEO says the flaws are "indeed real". | watchTowr, SecurityWeek |
| 20 Oct | CERT-EU tells organisations to prepare for immediate patching and to consider taking sites offline if they cannot patch. | RTE (Reuters) |
| 20 Oct, evening | PHP posts an advance notice: a release for two critical flaws, both CVSS v4.0 9.2, set for 21 Oct at 14:00 UTC, earlier if details go public. | php.net |
| 21 Oct, before release | Cloudflare deploys WAF rules for known vectors to all plans, including free. | Help Net Security, The Hacker News |
| 21 Oct, 11:26 UTC | watchTowr reports no in-the-wild exploitation, per The Hacker News. | The Hacker News |
| 21 Oct, about 13:45 GMT | PHP says fixed releases are live, shortly before the scheduled time. | KSL (Reuters), php.net |
| 21 Oct, 10:00 ET | Huntress says it has not seen in-the-wild exploitation across its partner base. | Huntress |
| 21 Oct | Sites in the Netherlands, Finland, Denmark and France are taken offline as a precaution. | KSL (Reuters) |
According to watchTowr and Huntress, the original embargo was meant to lift on Thursday 22 October. The two sources give different times of day for it, which no longer matters once the fixes shipped.
For the outages themselves, see our companion post on governments taking websites offline over PHP2Shell. Reuters, via KSL, lists the Port of Rotterdam, the Overheid.nl portal, the KNVB and several hospital sites in the Netherlands, along with services run by Valtori in Finland and Kombit in Denmark. Lukasz Olejnik of King's College London told Reuters: "The scale is huge."
The two flaws in plain language
PHP's own advisory on php.net and the two GitHub security advisories it links are the primary sources here. Both flaws are memory safety problems in how PHP sets up and tears down a request.
CVE-2026-109618, RCE via out-of-memory corruption. When PHP runs out of memory it jumps out of the current request immediately. PHP's advisory says that can happen while internal request data is only partly set up. Cleanup code then treats that half-built data as valid. The fix, per the GitHub advisory, removes that abrupt jump: PHP now stops at the next safe point, with a hard exit at a higher threshold.
CVE-2026-109619, RCE via stale global state. A PHP worker handles many requests in turn. The advisory says some state owned by one request can survive after its memory is freed, and a later request on the same worker can touch it before normal setup resets it. That is a use after free. The advisory names session upload progress handling as one confirmed path, and on PHP 8.5 the fatal error backtrace feature as another.
Two details matter for defenders. First, on mod_php the attack can fire during request startup, before any application code runs, so secure application code does not help. Second, The Hacker News reports that the flaws also allow reading live worker memory without code execution, which could expose tokens, passwords or keys from other requests.
The GitHub advisories credit four reporters. The Hacker News says the work came from Wiz Research, Calif and OpenAI's Codex Security team. According to Help Net Security, Wiz said frontier AI models lowered the barrier to building the exploit chain for bugs that had existed for a very long time. We cover that angle in AI found vulnerabilities: PHP2Shell and PwnEscape.
Who is affected
PHP's advisory says the risk covers every PHP installation that serves web requests. The GitHub advisories then explain that exposure differs a lot by server API (SAPI).
| SAPI | CVE-2026-109618 (OOM) | CVE-2026-109619 (stale state) |
|---|---|---|
| Apache mod_php | RCE validated with default limits and multi-worker prefork | RCE confirmed; startup diagnostics act as an early trigger |
| PHP-FPM | Likely susceptible by source analysis; no complete exploit shown | Conditional; needs a fatal error in the app plus the upload progress path, or a frontend sending PHP_VALUE settings |
| php-cgi | Listed as affected by php.net | Listed as affected by php.net |
| FrankenPHP | Likely susceptible by source analysis | No early trigger found in default config; PHP says that is not immunity |
| LiteSpeed (LSAPI) | Likely, but not validated | Conditional candidate |
On versions, sources disagree on how far back the bug goes. CERT-EU and the Australian Cyber Security Centre said every version from PHP 5 onward could be affected (RTE). The Hacker News and Tenable point to PHP 5.4 and later. The official advisories list only the supported branches.
| Branch | Status | What to install |
|---|---|---|
| 8.5 | Supported | 8.5.12 |
| 8.4 | Supported | 8.4.27 |
| 8.3 | Supported | 8.3.36 |
| 8.2 | Supported until 31 Dec 2026 | 8.2.35 |
| 8.1, 8.0, 7.4 | End of life upstream | Vendor backport, or PHP's minimal source backport branches |
| 7.3 and older, 5.x | End of life | Vendor backport if one exists; otherwise upgrade or take offline |
PHP says Linux distributions and LTS vendors got the patches before public release. Help Net Security, Huntress and Laravel News all note that the volunteer-run Remi repository would not have updates on release day. Laravel News adds that Laravel Vapor is not shipping a PHP 7 patch and tells users to move to PHP 8.
Is it being exploited?
This is disputed, and the answer changed by the hour on 21 October.
- Cloudflare's CTO Dane Knecht said early attacks were emerging and described the WAF rules as a stopgap only (KSL, Tenable).
- watchTowr's FAQ, updated 21 October, says its honeypot network observed exploitation. The Hacker News separately reports that watchTowr saw none as of 11:26 UTC that day.
- Huntress, at 10:00 ET on 21 October, had seen none across its partners. The ACSC said it was not aware of active exploitation (RTE). The Hacker News reports the Dutch national cyber security centre had not seen abuse.
- SecurityWeek reports that Sansec expected mass exploitation within minutes of the patch release.
- Tenable notes public exploit code was circulating but unverified, and warns it could contain malware.
- Neither CVE was in CISA's Known Exploited Vulnerabilities catalog when watchTowr and The Hacker News wrote.
The safe reading: assume scanning and attempts are under way, and treat an unpatched internet-facing server as at risk now.
Workarounds, and why they are only partial
PHP's release notes are blunt: "There are no complete mitigations, updating is the only safe choice." PHP core developer Gina Peter Banyard said the same before release, per The Hacker News.
If you truly cannot upgrade today, PHP's advisory lists measures that close specific paths:
; Apply in php.ini, the FPM pool or Apache config, not ini_set() or .user.ini
memory_limit = -1 ; enforce with php_admin_value
post_max_size = 8M ; 32M if you need uploads
session.upload_progress.enabled = 0 ; restart all workers afterwards
; PHP 8.5 only
fatal_error_backtraces = 0
Here is what each one does not do, according to the GitHub advisories:
- memory_limit = -1 narrows CVE-2026-109618, but if the operating system refuses an allocation, the vulnerable path can still be reached.
- Disabling session upload progress blocks the demonstrated session path for CVE-2026-109619 only. It does nothing for CVE-2026-109618.
- fatal_error_backtraces = 0 removes the confirmed 8.5 trigger but leaves other stale state.
- RLIMIT_AS and RLIMIT_DATA make things worse, because they cause the exact allocation failure the bug needs.
- A WAF only sees traffic routed through it, and Cloudflare itself calls its rules a stopgap.
Laravel News adds that ini_set() and .user.ini apply too late to help. Front-end request size limits and blocking multipart bodies where the app does not need them reduce exposure but do not fix the bug.
What to do now
-
Find every PHP that serves web traffic. Hosts, VMs, containers, control panels, vendor appliances. Huntress specifically calls out cPanel, Plesk, bundled Windows software and CMS hosts.
-
Check the version of the SAPI that actually serves requests, not just the CLI. They can be different packages or binaries.
php -v
php-fpm8.3 -v # adjust to your FPM binary name
apachectl -M 2>/dev/null | grep -i php # is mod_php loaded?
ps -eo comm | grep -E 'php-fpm|php-cgi|lsphp|frankenphp|httpd|apache2' | sort -u
- On distro packages, look for the CVE in the changelog. The Hacker News notes a patched package can carry an older looking version number.
# Debian and Ubuntu
dpkg -l | grep -E '^ii +(php|libapache2-mod-php)'
apt changelog php8.3-fpm | grep -m1 CVE-2026-109618
# RHEL, Alma, Rocky, SUSE
rpm -qa | grep -i php
rpm -q --changelog php-fpm | grep -m1 CVE-2026-109618
- Check container images and rebuild them. Pull the patched base image, rebuild, and redeploy. A running container does not change because the tag moved.
docker run --rm --entrypoint php your-registry/app:prod -v
docker build --pull -t your-registry/app:prod .
- Restart every worker after upgrading. Old code stays in memory until the process exits.
sudo systemctl restart php8.3-fpm
sudo systemctl restart apache2 # or httpd
php -i | grep -E 'memory_limit|post_max_size|session.upload_progress.enabled'
Note that the last command shows CLI settings. Check FPM pool files and Apache config for the values your web workers use.
-
If you cannot patch, follow CERT-EU and the NCSC: take the site offline or put it behind a VPN until you can.
-
Watch for signs of compromise. Huntress suggests alerting when web worker processes spawn shells, interpreters or download tools. The Hacker News lists unusual multipart requests followed by memory limit errors, oversized PHPSESSID cookies, and unexplained worker restarts. If you find any, isolate the host, keep logs, and rotate secrets that lived on it.
-
Review limits after patching. Per The Hacker News, the fix adds a hard memory limit that ends the process and skips shutdown handlers, so revisit memory_limit and post_max_size.
For a deeper fleet-wide walk through, see find and patch every PHP runtime after PHP2Shell.
What would have helped
PHP gave roughly a day of notice before the fixes landed. Teams that already knew where PHP ran, and could rebuild and restart fast, were patching within the hour. Teams that had to discover their PHP estate first were the ones deciding whether to go dark.
Practices any team can use:
- A runtime inventory, not just a dependency inventory. Most teams can list their Composer packages. Fewer can list every PHP binary, its SAPI, its version and where it runs. That list is what you need on a day like 21 October.
- A rebuild and redeploy path you have tested. If your images pin a PHP base image, you need a pipeline that can rebuild all of them and roll them out in hours. Practise it on a quiet week.
- End of life tracking. PHP 8.1 and older no longer get upstream fixes, and 8.2 ends on 31 December 2026. Teams on EOL branches spent release day hunting for backports.
- Restart discipline. Package managers do not always restart PHP-FPM or Apache. Make the restart part of the patch runbook and verify it.
- Configuration that shrinks exposure regardless. Disable session upload progress if you do not use it (PHP suggests keeping it off after patching), enforce request size limits at the proxy, and remove deprecated per-directory INI settings.
- Process monitoring on web servers. A PHP worker that spawns a shell is rarely legitimate. That alert works for this bug and the next one.
- A pre-agreed offline decision. Know which sites can go dark, who can authorise it, and what customers see. The organisations that went offline on 21 October had to make that call under pressure.
- Secrets that are cheap to rotate. If worker memory can leak, short-lived tokens and a rotation runbook limit the damage.
Our older posts on PHP security and CVE-2024-4577 in PHP-CGI show the same pattern: runtime flaws land on whoever runs the server, not on the application author.
Where Safeguard fits
Safeguard would not have prevented PHP2Shell, and it does not patch servers. It helps with the "where is it and what do we change" part.
- Finding PHP in images and SBOMs. Running
safeguard scan --image <name>builds an SBOM of a container image and lists the PHP build it ships, so you can compare each image against the fixed versions above.safeguard scan --sbom <file>does the same for SBOMs your vendors give you, andsafeguard scan --dir .covers repositories. Results land as JSON under ./output. Matching against vulnerability databases depends on those databases carrying the new CVEs, so for a flaw this fresh, check the PHP version in the SBOM directly rather than waiting for a finding. - "Which projects ship this version?" The platform shows which projects contain a given component and version, which turns "are we exposed" into a list. Our post on SBOM incident response explains that workflow.
- Gates that stop old images shipping. Once the CVEs are in your findings, policies and gates evaluated in the platform can hold back a build that still carries them.
- Making the change. The Safeguard CLI's assistant can edit a Dockerfile to move to a patched base image and run your build and tests, asking for approval before each command under its default permission mode. You can send that work from the desktop or phone app to a computer running the CLI and approve each command there. For application dependencies, autonomous remediation can open fix PRs, and it is off by default.
Where it does not help: PHP installed by hand on a VM or bare metal that you never scan, PHP inside managed hosting, control panels or appliances you cannot inspect, restarting workers, blocking attack traffic, or detecting a break-in. Reachability analysis also does not lower the priority here, because the bug triggers in the runtime before your code runs. Database matching can lag a same-day advisory, and distro backports can make version matching noisy, so confirm against your vendor's changelog.
To try it, download Safeguard at https://safeguard.sh/download and read the CLI docs at https://docs.safeguard.sh/docs/cli .
Common mistakes
- Checking only the CLI.
php -von the host tells you nothing about the PHP inside a container or the mod_php module Apache loaded. - Trusting the version string on distro packages. Backports keep old numbers. Check the changelog for the CVE.
- Upgrading without restarting. Workers keep running the old code.
- Treating the WAF as the fix. It covers proxied traffic only, and only known vectors.
- Setting workarounds in .user.ini or ini_set(). They apply too late.
- Expecting WordPress or Laravel updates to fix it. CMS and framework updates change application code, not the PHP runtime. Whoever runs the server has to update PHP.
- Waiting on a volunteer repository. Remi had no day-one update; switch to distro packages or build from source if you need the fix now.
- Running unverified exploit code to "test". Tenable warns it may contain malware.
FAQ
Is PHP2Shell being exploited in the wild?
Sources disagree. Cloudflare reported early attacks and watchTowr's FAQ reports honeypot hits, while Huntress, the ACSC and the Dutch NCSC said they had not seen exploitation when they wrote. Neither CVE was in CISA KEV at the time. Patch as if it is.
What does the CVSS score mean here?
PHP rated both flaws 9.2 under CVSS v4.0. Tenable and The Hacker News note that early leak posts claimed 10.0, which was not PHP's rating. The vector marks attack requirements as present, reflecting that some paths depend on configuration.
My distro shows PHP 8.1 or an old 8.3 number. Am I patched?
Possibly. Distros and LTS vendors received patches in advance and often backport without bumping the upstream version. Search the package changelog for CVE-2026-109618 and CVE-2026-109619.
Is PHP-FPM safe?
No. PHP's advisory says FPM's design blocks one mod_php sequence and no complete FPM exploit for CVE-2026-109618 was shown, but CVE-2026-109619 was validated on FPM under certain conditions. Upgrade FPM like everything else.
Do I need to rotate secrets?
If an unpatched server was internet facing, consider it. The Hacker News reports the flaws can leak worker memory, which may hold tokens and keys from other requests. If you see any sign of compromise, rotate everything on that host.
Are PHP 7.4, 8.0 and 8.1 fixed?
Not through normal releases. PHP published minimal source backport branches for those three, and some vendors ship backported packages. Anything older needs a vendor fix, an upgrade, or to come off the internet.
Try it yourself
This demo shows the Safeguard CLI fixing a dependency finding, asking before each command and pushing nothing.
Click through it at your own pace, or open it full screen.
This one sets up the local runner on your own machine, approves it with a device code, and scans from the terminal.
Click through it at your own pace, or open it full screen.
Quick check
Which SAPI does PHP rate as highest risk for PHP2Shell?
Apache mod_php, because a demonstrated exploit triggers during request startup before any application code runs.
Does setting session.upload_progress.enabled = 0 fix PHP2Shell?
No. It blocks one demonstrated path for CVE-2026-109619 and does nothing for CVE-2026-109618. Upgrading and restarting workers is the only complete fix.
Sources
- PHP news archive: advance notice, security advisory and 21 Oct releases (php.net)
- GHSA-w8hw-w9fx-j79w: RCE via OOM corruption, CVE-2026-109618 (php-src on GitHub)
- GHSA-6wmf-4rv5-p3rp: RCE via stale global state, CVE-2026-109619 (php-src on GitHub)
- Help Net Security: PHP2Shell vulnerabilities patched
- The Hacker News: PHP issues emergency patches for two critical flaws
- Huntress: php2shell, leaked critical PHP vulnerabilities
- Tenable: PHP2Shell frequently asked questions
- watchTowr: PHP CVE-2026-109618 FAQ
- SecurityWeek: PHP2Shell mass exploitation looms for leaked critical PHP flaws
- Laravel News: PHP critical RCE security releases
- KSL (Reuters): Cyber agency warns websites may go dark as PHP prepares critical fix
- RTE (Reuters): EU cybersecurity agency warning on PHP
Last reviewed: 21 October 2026. This is a developing story; check the linked advisories for the latest status.