PHP2Shell
Two critical flaws in PHP itself let an attacker run their own code on a server without logging in. Every PHP release from 5.4 to 8.5.11 is affected, AI helped find them, and the details leaked before the patch. What went wrong, how the attack works, and exactly what to update.
- TL;DR and key numbers
- How PHP handles a request
- The bug family in detail
- The insight: errors that leave a mess
- How the attack works
- How AI found it
- Leak, attacks and response
- How big is the blast radius
- Which versions are fixed
- Check and patch your server
- Why 70% of the web had to update
- Who should worry most
- Caveats
- FAQ
- Glossary and sources
TL;DR
- PHP2Shell is the name for two critical vulnerabilities in the PHP engine itself, CVE-2026-109618 and CVE-2026-109619, patched on 21 October 2026.
- They allow unauthenticated remote code execution and memory disclosure: an attacker who can send requests to a PHP site can run their own code with the PHP process's privileges.
- The root cause: when PHP hits a fatal error mid-request, usually out of memory, it can leave internal state behind. The next request on the same worker then trusts that stale state.
- Every PHP version from 5.4 (2012) to 8.5.11 is affected by at least one of the bugs. Fixed in 8.5.12, 8.4.27, 8.3.36 and 8.2.35. PHP 8.1 and older are end of life and get no official release.
- Researchers at Wiz and Calif found them independently with help from AI models. Wiz confirmed a working attack on Drupal one day after finding the first bug.
- Details leaked before the planned release, attacks were reported, and the NSA advised anyone on PHP to update immediately or take systems offline.
How PHP handles a request
PHP runs a huge share of the web: WordPress, Drupal, Joomla and Magento are all built on it. When someone visits a PHP site, the web server hands the request to a PHP worker, a long-running process that executes the site's code and returns the page.
Popular platforms built on PHP. A bug in PHP itself reaches all of them at once.
One worker, many requests
Workers are reused. The same process handles one request, cleans up, and handles the next. Each request goes through the same life cycle:
That clean slate is the assumption everything rests on. Each request should start fresh, with nothing left over from whoever came before. PHP2Shell is what happens when that assumption breaks.
Memory limits: PHP caps how much memory one request may use. Go over it and PHP stops the request with a fatal "out of memory" error. That limit is meant to protect the server, and it turns out to be the trigger.
The bug family in detail
Wiz describes four bugs under the two CVEs. They share one pattern: PHP handles a fatal error, usually running out of memory, while it is processing a request, and leaves internal state behind that a later request on the same worker reuses.
| Bug | CVE | What goes wrong | Impact |
|---|---|---|---|
| Upload-progress use-after-free | 109618 | During a multipart (file upload) request, an out-of-memory error frees the request's memory while a global pointer still points at it. | Remote code execution |
| Session-ID memory disclosure | 109618 | An out-of-memory error early in start-up leaves a session-ID pointer dangling. A later multipart request can read the freed memory and send part of it back. Works even if the app never calls session_start(). | Memory leak to attacker |
| Fatal-error backtrace use-after-free | 109619 | After a fatal out-of-memory error, PHP keeps a global pointer to the backtrace. The next request can touch it before it is reset. | Cross-request memory corruption |
| OPcache type confusion | 109619 | OPcache shares compiled code across workers. An allocation failure can leave shared slot metadata out of sync, so one worker gets a pointer of the wrong type. | Memory corruption across workers |
PHP's advisories title them "RCE via OOM corruption" (CVE-2026-109618) and "RCE via stale global state" (CVE-2026-109619). Wiz notes other variants likely exist; the patch fixes the root cause.
Google's one-line versions
- CVE-2026-109618: out-of-memory handling can interrupt PHP while request data is only partly set up, and clean-up may then treat the invalid data as valid.
- CVE-2026-109619: request-owned state can survive after its memory has been freed, and a later request on the same worker may use it before normal set-up resets it.
The insight: errors that leave a mess
Most memory bugs come from a mistake in the normal path. These come from the error path: the code that runs when something has already gone wrong. It is exercised far less often, so problems there can hide for years.
Think of PHP as a hotel, each request as a guest and memory as the rooms. A guest is thrown out in a hurry and the room is freed, but the register still says "room 204 holds PHP's important data". The next guest moves into room 204, PHP reads the register and trusts whatever it finds there.
- Thrown out in a hurry = fatal out-of-memory error
- Room freed = request memory released
- Register not updated = a global pointer left dangling
- Next guest = the next request on the same worker
- Trusting the room = use-after-free
The analogy is a simplification. The real bugs involve specific internal pointers and caches (section 3), and turning them into reliable code execution depends on version, configuration and memory layout.
How the attack works
At a high level, and without the details that would make it a recipe, an attack has four stages.
Push a request over the memory limit
The attacker sends a request, often a large multipart upload, built to make PHP run out of memory at the wrong moment. Google notes the attacks may use large payloads for this.
PHP aborts, state is left behind
The fatal error stops the request mid-way. Memory is freed, but a global pointer or cache entry still refers to it.
Reclaim the freed memory
A follow-up request lands on the same worker. Its own data can end up in the memory the stale pointer still refers to.
PHP trusts it
PHP uses the stale pointer as if it were valid internal data. That gives memory corruption, which can be steered into running the attacker's code, or a leak of process memory.
No login needed. Wiz demonstrated unauthenticated remote code execution against the default latest container images of WordPress, Drupal and Joomla, plus memory disclosure. Attackers don't need an account on the site.
How AI found it
Two teams found the bugs independently in August 2026, both with help from AI models.
Used its own tool Wiz Atlas with Gemini 4 Argon and GPT-5.6 Sol. Wiz says the models helped find the bug, build the exploit, adapt it to different PHP versions and memory layouts, write detections and check the patch, and that one researcher did in a week what would previously have taken a top team months.
Ryan Austin of Calif, part of OpenAI's "Patch the Planet" project, found the flaws using GPT-5.6 Sol. Calif later published a comic-style timeline of the discovery.
| Date | What happened |
|---|---|
| 2024 | A PHP core developer spotted the out-of-memory problem behind one bug in an audit. It wasn't fixed: no agreed fix and no known exploit. |
| 19 Aug 2026 | Wiz finds the first bug. |
| 20 Aug | Unauthenticated remote code execution confirmed against Drupal: one day later. |
| 21 Aug | Confirmed against WordPress. |
| 24 Aug | Reported to the PHP security team. |
| 21 Sep | PHP acknowledges the reports. |
| 21 Oct | Patched releases and public disclosure. |
Leak, attacks and response
The embargo broke
The details were under embargo until Thursday 22 October, 15:00 UTC, to give maintainers and vendors time. They leaked on Tuesday 20 October; watchTowr confirmed the flaws were real and reproduced CVE-2026-109618. PHP moved the release forward to Wednesday 21 October, and both GitHub advisories went live at 13:34 UTC, 26 minutes before the announced time. Proof-of-concept code circulated before the embargo ended, after Chainguard shipped patched software early.
Were attackers already using it?
| Who | What they reported |
|---|---|
| Cloudflare | Early attacks emerging; deployed WAF rules for all customers, free tier included, at 03:02 UTC, as a stopgap. |
| Amazon | An exploitation attempt in its MadPot sensors on 17 October, four days before disclosure. |
| watchTowr | Exploitation in the wild seen by its honeypots by 21 October. |
| CISA | Had not observed exploitation as of 21 October. |
What governments and sites did
- NSA: update immediately, or take systems offline until you can.
- UK NCSC: inventory PHP use, patch internet-facing systems, monitor them, or take them offline; be wary of backdoors.
- Offline as a precaution: the Dutch government portal Overheid.nl, all Finnish government public-facing web services, and the Dutch NCSC's own site.
- Others hit: 4chan and Something Awful went offline, the Internet Archive briefly shut down, and Wikimedia shut down services including Phabricator. Open LMS took all customer sites offline.
How big is the blast radius
A flaw in one app affects that app's users. A flaw in the language runtime affects everything built on it. Wiz compared PHP2Shell to Log4Shell and Heartbleed for exactly that reason.
Web properties and hosts: Censys, via Krebs. Companies: Veridion, via Wikipedia, which notes most have fewer than 50 employees and another 21.9 million companies use PHP without exposing a version. These measure different things, so compare them loosely. Bar widths are to scale (our arithmetic).
About 70% of websites use PHP (Wiz; Wikipedia says about 69%). That is why Krebs wrote that nearly 70 percent of websites needed to update their core software.
Which versions are fixed
| Branch | Status | Fixed in | What to do |
|---|---|---|---|
| PHP 8.5 | Supported | 8.5.12 | Update now |
| PHP 8.4 | Supported | 8.4.27 | Update now |
| PHP 8.3 | Supported | 8.3.36 | Update now |
| PHP 8.2 | Supported | 8.2.35 | Update now |
| PHP 7.4 – 8.1 | End of life | Source patches only | Upgrade to 8.2+; no official binaries |
| PHP 5.4 – 7.3 | End of life | No fix | Upgrade to 8.2+ |
PHP's maintainers published temporary mitigations but said there is no complete mitigation and that updating is the only safe choice.
Check and patch your server
1 · Find out which PHP you run
# CLI version php -v # the version your web workers run (can differ from the CLI) php-fpm -v
Anything below 8.2.35 / 8.3.36 / 8.4.27 / 8.5.12 on its branch is vulnerable. Also check what your site reports, for example in phpinfo() on a private page, because web servers can run a different PHP than your shell.
2 · Update
Ubuntu / Debian packages (Ubuntu released updated PHP packages; package names depend on your version and repository, so this is an example):
sudo apt update # upgrade the PHP packages you have installed, e.g. for 8.3 sudo apt install --only-upgrade php8.3 php8.3-fpm php8.3-cli # restart the workers so no old process keeps running sudo systemctl restart php8.3-fpm
Containers: pull the patched base image, rebuild and redeploy. Google's advice for Cloud Run and GKE is the same: update the image, then redeploy.
# pin a fixed release instead of a floating tag FROM php:8.4.27-fpm
Managed platforms: some patch automatically. Google says supported App Engine standard runtimes were patched for you; apps on PHP 8.1 or earlier there still need upgrading and redeploying. Check your host's security bulletin.
3 · Restart, then confirm
Workers live a long time. Restart PHP-FPM or your web server after updating, then run php-fpm -v again and check the version your site reports.
4 · If you can't patch today
- Put a WAF in front. Cloudflare, Fastly, Vercel and Google Cloud Armor shipped rules. They are stopgaps, not fixes.
- Limit request body size. The attacks can use large payloads to force out-of-memory errors, so cap uploads at what your app actually needs (Google's advice).
- Watch for the signs Wiz lists: unusual multipart requests followed by memory-limit errors, repeated HTTP 500s, unusually large or malformed
PHPSESSIDcookies, and unexplained PHP worker churn. - Last resort: take the site offline until it is patched, as the NSA and NCSC advised.
About 70% of websites run on PHP, and every PHP release from 5.4 onwards is affected by at least one of these bugs. A flaw in the runtime doesn't care which app sits on top, so a WordPress blog, a Drupal government portal and a Magento shop were all exposed at once.
The second half of the story is speed. The bugs sat in the error path for more than a decade; once AI-assisted researchers looked, a working attack on Drupal existed one day after the first bug was found, and the details leaked before most sites could patch.
Who should worry most
Act today
- Any internet-facing site on PHP 5.4 to 8.5.11
- Self-managed servers and VPSs running WordPress, Drupal, Joomla or Magento
- Anything still on PHP 8.1 or older: there is no official fixed release
- Container images built on old PHP tags that haven't been rebuilt
Probably handled, but verify
- Managed platforms that patch the runtime for you (check their bulletin)
- Sites behind a WAF with the new rules, as a temporary shield only
- Internal tools with no internet exposure (still patch them)
Caveats
- Exploitation reports differ. Cloudflare, Amazon and watchTowr reported attacks or attempts; CISA had not observed exploitation as of 21 October.
- Two scores. PHP rates each CVE 9.2 (CVSS v4.0). watchTowr rated it 10.0. This article uses PHP's figure.
- 70% is approximate. Wiz says 70%, Wikipedia about 69%.
- Exact preconditions aren't fully public. Wiz says differences in PHP versions, configuration and application behaviour can break the assumptions an exploit relies on. Treat every affected version as vulnerable.
- "14 years" and "one day". 14 years counts from PHP 5.4's 2012 release to the 2026 disclosure (our arithmetic). "One day" is Wiz's gap between finding the first bug (19 August) and RCE on Drupal (20 August).
- "No official update" for old versions. PHP 7.4 to 8.1 did get source patches, but no official releases or binaries. Older versions get nothing.
- A fast-moving story. Written on 23 October 2026, two days after disclosure. Check the PHP advisories for updates.
FAQ
Is my WordPress site affected?
If it runs on PHP 5.4 to 8.5.11, yes. The bug is in PHP, not WordPress, so updating WordPress plugins doesn't fix it. Update PHP itself.
Does the attacker need to log in?
No. Wiz demonstrated unauthenticated remote code execution against default WordPress, Drupal and Joomla images.
Is a WAF enough?
No. Cloudflare and others called their rules a stopgap, and PHP says updating is the only safe choice.
I'm on PHP 8.1. Is there a patch?
Source patches exist for 7.4 to 8.1, but PHP is not shipping official releases for them. The safe path is upgrading to 8.2 or newer.
Why is it called PHP2Shell?
Because the end result is a shell: attackers can run commands on the server and, as Wiz expects, install web shells for lasting remote control.
Did AI write the exploit?
AI models helped. Wiz used them to find the bug, build and adapt the exploit, write detections and validate the patch, with researchers driving the work.
Glossary
- RCE
- Remote code execution: an attacker runs their own code on your server over the network.
- CVE
- A public ID for a specific vulnerability, such as CVE-2026-109618.
- CVSS
- A 0 to 10 severity score. 9.0 and above is "critical".
- Use-after-free
- Code keeps using memory after it has been freed, so whoever reclaims that memory controls what the code reads.
- Out of memory (OOM)
- A request uses more than PHP's memory limit, so PHP stops it with a fatal error.
- PHP worker
- A long-running process (for example under PHP-FPM) that handles one request after another.
- OPcache
- PHP's cache of compiled code, shared between workers to save time.
- Multipart request
- The kind of HTTP request browsers use to upload files.
- WAF
- Web application firewall: filters malicious requests before they reach your app.
- End of life (EOL)
- A version that no longer gets official fixes.
- Embargo
- An agreed delay before a vulnerability is made public, so fixes can be prepared.
- PHP2Shell research write-up. Wiz Research, 21 Oct 2026.
- Responding to core PHP vulnerabilities CVE-2026-109618 and CVE-2026-109619. Google Cloud blog, Oct 2026.
- Widespread PHP flaw may cause many site outages today. Krebs on Security, 21 Oct 2026.
- Attackers exploit leaked zero-day flaws in widely used PHP. BankInfoSecurity, Oct 2026.
- The internet is having a very bad cybersecurity day. TechCrunch, 21 Oct 2026.
- PHP2Shell. Wikipedia, as of 22 Oct 2026.
- PHP security advisories GHSA-w8hw-w9fx-j79w (CVE-2026-109618) and GHSA-6wmf-4rv5-p3rp (CVE-2026-109619).