14 min to read
PHP2Shell: The PHP Flaws Under Attack and What to Do Now
Two critical bugs in PHP itself, and exploitation started before the patch
Most critical web bugs live in a plugin, a CMS or one vendor’s appliance. PHP2Shell is different: the flaws are in PHP itself, the language runtime behind WordPress, WooCommerce, Magento, Drupal, Joomla, Laravel apps and countless custom portals. Before a single line of your application code runs, one unauthenticated HTTP request may be enough to reach the vulnerable code.
PHP shipped emergency fixes on 21 October 2026. Attackers got there first. Amazon’s honeypots logged an exploitation attempt on 17 October, four days before the patch, and scanning has been broad ever since.
TL;DR / Key takeaways
- CVE-2026-109618 and CVE-2026-109619 (“PHP2Shell”) are memory-safety flaws in PHP core, each rated CVSS 9.2, that can lead to unauthenticated remote code execution as the web server user.
- Every PHP install that serves web requests is in scope: PHP-FPM, Apache
mod_php(highest risk), php-cgi, FrankenPHP and LiteSpeed.- Fixed versions: PHP 8.5.12, 8.4.27, 8.3.36, 8.2.35. PHP 7.4/8.0/8.1 get source backports only, and PHP 7.3 and older have no fix at all.
- Exploitation attempts began before disclosure. Reports on whether any attacks have succeeded still conflict, so assume it is only a matter of time.
- Patch and restart every worker. Config tweaks and WAF rules only reduce exposure. They don’t fix the bugs.
What happened
On 21 October 2026, Wiz Research disclosed PHP2Shell together with the PHP security team, Calif and OpenAI, and patched PHP releases came out the same day (Wiz, BleepingComputer). Wiz described the findings as ranking “among the most severe vulnerabilities discovered in PHP, and arguably in software history” (Help Net Security). Kevin Beaumont called it “one of the biggest vulns in years” and predicted a “mass of incidents”.
AI played a big part on the research side. Wiz says frontier models (Gemini 4 Argon and GPT-5.6 Sol, alongside its own tooling) helped with discovery, exploit development and patch validation. In its view, AI substantially lowered the expertise needed to turn a very complex bug chain into a working exploit (Wiz). Defenders should take that seriously, because the same lowered barrier applies to attackers.
Timeline
| Date (2026) | Event |
|---|---|
| 19 Aug | Wiz finds the first bug. Unauthenticated RCE confirmed against Drupal (20 Aug) and WordPress (21 Aug). |
| 24 Aug | Reported to the PHP security team. |
| 21 Sep | PHP acknowledges and begins a coordinated fix. Linux distributions receive patches ahead of release. |
| 17 Oct | Amazon’s MadPot honeypot records the first exploitation attempt, four days before disclosure. |
| 20 Oct | PHP warns administrators that emergency patches for two critical flaws are coming. |
| 21 Oct, ~02:00 UTC | Proof-of-concept exploits appear while the embargo is still in place. Details had leaked, so PHP brings the release forward by a day. |
| 21 Oct, ~14:00 UTC | Embargo lifts. PHP 8.5.12 / 8.4.27 / 8.3.36 / 8.2.35 released. Broad exploitation attempts follow within hours. CISA urges organisations to patch or consider taking systems offline. |
| 22 Oct | Palo Alto Networks says all PAN-OS and Panorama versions are affected, with fixes pending. Fortinet and Cisco are reviewing their products. |
| 23 Oct | PHP discloses a third, unpatched RCE (CVE-2026-115560) that affects only unusual configurations, and recommends session.upload_progress.enabled=0. |
Sources: Wiz, AWS Security Blog, The Hacker News, Help Net Security, BleepingComputer.
How the flaws work (conceptually)
Both bugs come from the same root problem. When a PHP request ends abnormally, especially through an out-of-memory error, PHP can leave its internal memory in an inconsistent state (BleepingComputer).
- CVE-2026-109618 (“RCE via OOM corruption”). An out-of-memory error during request parsing can interrupt PHP while request data is only half-initialised. Cleanup code then treats that data as valid. Datadog’s analysis traces it to hash-table insertion in the Zend engine and notes that the vulnerable path is reachable with an unauthenticated HTTP POST. Application-level authentication can’t block it, because PHP processes the request body before your code runs (Datadog Security Labs).
- CVE-2026-109619 (“RCE via stale global state”). Request-owned state can outlive the memory behind it, so a later request on the same worker may use freed memory (a use-after-free). The known paths go through session upload progress (confirmed on
mod_phpand PHP-FPM) and, on PHP 8.5, fatal-error backtraces (Datadog, Help Net Security).
The exploit chains aren’t trivial. They need precise request sizing and an ASLR bypass. Wiz showed a memory-disclosure primitive that works even if the app never calls session_start(), and it demonstrated RCE against stock latest container images of WordPress, Drupal and Joomla (Wiz). In other words, “it’s hard to exploit” isn’t a reason to wait.
Am I affected?
Almost certainly yes, if you run PHP on anything internet-facing. The affected and fixed versions are:
| PHP branch | Status | What to do |
|---|---|---|
| 8.5 | Vulnerable before 8.5.12 | Upgrade to 8.5.12 |
| 8.4 | Vulnerable before 8.4.27 | Upgrade to 8.4.27 |
| 8.3 | Vulnerable before 8.3.36 | Upgrade to 8.3.36 |
| 8.2 | Vulnerable before 8.2.35 | Upgrade to 8.2.35 |
| 7.4, 8.0, 8.1 | All versions vulnerable, end-of-life | Distro/LTS vendor package, PHP’s source backport, or migrate |
| 7.3 and older (incl. 5.x) | All versions vulnerable, no fix | Migrate, or isolate from the internet |
Sources: watchTowr FAQ, Datadog.
Keep these in mind:
- Distro backports don’t always change the version number. A Debian, Ubuntu or RHEL package might report an “old” version and still be fixed. Check your distribution’s security tracker, not just
php -v. - The CLI isn’t the web runtime. Containers, control panels and bundled stacks often ship their own PHP. Check the binary that actually serves requests.
- Appliances count too. Palo Alto Networks says all PAN-OS and Panorama versions are affected and fixes haven’t shipped yet. Fortinet (12 products) and Cisco (31 products and services) are still investigating (Help Net Security). Expect more vendor advisories over the coming weeks.
- Shared hosting. If your shop runs on shared or managed hosting, your provider controls the PHP binary. Ask them, in writing, which version and patch level you’re on.
The exposure problem
The installed base is huge and old. VulnCheck counted 2,608,039 internet-facing PHP hosts, with over 700,000 running PHP 3.x–7.3 and about 400,000 on 7.4–8.1 (The Hacker News). A separate Shodan-based count found that 59% of hosts that report a version run a branch with no official fix (CybelAngel). Researcher Hal Pomeranz warned of a “long tail” of embedded and unmaintained installs that will never be patched (Help Net Security).
Exploitation status: what we know (and don’t)
- Confirmed attempts: Amazon saw attempts from 17 October, then multiple PoCs and varying payloads on 21 October, which suggests several actors. AWS CISO CJ Moses said “PHP2Shell is now seeing broad exploitation attempts in the wild” (AWS, BleepingComputer). watchTowr’s honeypots have seen exploitation since 21 October (watchTowr). Pantheon blocked more than 60,000 suspicious requests in the first day, and Cloudflare says attackers are mutating payloads to get past its rules (The Hacker News).
- Successful compromises: still unclear. Datadog cites Patchstack reports of active exploitation cases. A Dataminr report on 22 October, by contrast, saw only scanning, fingerprinting and non-working exploits, while warning that success “remains only a matter of time” (Datadog, BleepingComputer). This is still developing.
- KEV status: As of 22 October, CISA hadn’t added the CVEs to its Known Exploited Vulnerabilities catalog (watchTowr). Don’t wait for that before acting.
Detection: what to look for
None of these signals is conclusive on its own. Combine them, and remember that a successful exploit may return HTTP 200 without crashing anything (Datadog). Investigations should start from 17 October, not the disclosure date (AWS).
1. The strongest signal: web workers spawning shells. A www-data/apache/PHP-FPM process that launches sh, bash, curl or wget deserves immediate attention. Here’s a Sigma-style rule for Linux process telemetry (auditd, Sysmon for Linux, EDR):
title: Shell or downloader spawned by PHP / web server process
status: experimental
logsource:
product: linux
category: process_creation
detection:
parent:
ParentImage|endswith:
~|-| '/php~|-|fpm'
~|-| '/php~|-|fpm8.2'
~|-| '/php~|-|fpm8.3'
~|-| '/php~|-|fpm8.4'
~|-| '/php~|-|fpm8.5'
~|-| '/apache2'
~|-| '/httpd'
~|-| '/lsphp'
~|-| '/frankenphp'
child:
Image|endswith:
~|-| '/sh'
~|-| '/bash'
~|-| '/dash'
~|-| '/curl'
~|-| '/wget'
~|-| '/python3'
~|-| '/perl'
condition: parent and child
falsepositives:
~|-| Applications that legitimately call system commands (baseline first)
level: high
2. PHP error logs: memory exhaustion during request start-up. Datadog points to fatal out-of-memory errors that report in Unknown on line 0, which means the memory ran out before any script line executed:
grep ~|-|E "Allowed memory size of [0~|-|9]+ bytes exhausted.*in Unknown on line 0" \
/var/log/php*~|-|fpm.log /var/log/apache2/error.log /var/log/httpd/error_log 2>/dev/null
3. Worker crashes. Failed attempts often crash workers, for example AH00052: child pid ... exit signal Segmentation fault (11) in Apache logs, or unexplained PHP-FPM worker churn (Datadog, Wiz).
grep ~|-|E "Segmentation fault|exited on signal (11|6)" \
/var/log/apache2/error.log /var/log/php*~|-|fpm.log 2>/dev/null | tail ~|-|50
4. Suspicious request shapes (WAF, reverse proxy or full-body logs):
- Form-upload POSTs containing the string
PHP_SESSION_UPLOAD_PROGRESS(AWS). - Unusually large or malformed
PHPSESSIDcookies, and odd multipart requests followed by memory errors or repeated HTTP 500s (Wiz). x-www-form-urlencodedPOSTs with extremely long field names (one example was about 3.5 MB), or binary/null bytes in form fields (Datadog).
A Splunk example for proxy or WAF logs (adjust field names to your sourcetype):
index~|=|web (method~|=|POST) earliest~|=|10/17/2026:00:00:00
| eval big_body~|=|if(bytes_in > 2000000, 1, 0)
| where big_body~|=|1 OR (like(cookie, "%PHPSESSID~|=|%") AND len(cookie) > 512)
| stats count values(status) as statuses dc(uri_path) as paths by src_ip, host
| sort ~|-| count
5. Published infrastructure. AWS published these IPs as observed sources. They belong to shared anonymisation services, so AWS recommends investigating activity from them rather than blocking them outright (AWS):
103.216.220.92 (17 Oct 2026)
31.223.184.166 (21 Oct 2026)
37.19.200.5 (21 Oct 2026)
134.209.159.64 (21 Oct 2026)
103.114.163.188 (21 Oct 2026)
95.217.98.37 (21 Oct 2026)
Also check for new or modified PHP files in web roots and upload directories since 17 October. Web shells are the usual follow-on from a PHP RCE.
Prioritised action checklist
Immediate (today)
- Inventory every PHP runtime that serves web traffic, internet-facing first. Include containers, control panels, appliances and anything a hosting provider manages for you.
- Patch to 8.5.12 / 8.4.27 / 8.3.36 / 8.2.35, or apply your distribution’s fixed package.
- Restart or replace every PHP worker (PHP-FPM pools, Apache) and rebuild container images. A patched binary on disk doesn’t protect a process that’s still running the old code (Datadog).
- Anything you can’t patch today: restrict it from the internet. The UK NCSC advises considering taking it offline (Help Net Security).
Interim hardening (only while you patch, never instead of it)
These settings reduce exposure but don’t fully fix the bugs. Both PHP core developers and AWS say patching is the only complete remediation (BleepingComputer, AWS). Test them on staging first, because they can affect uploads and memory behaviour.
; php.ini / pool config ~|-| temporary PHP2Shell exposure reduction
session.upload_progress.enabled ~|=| 0 ; CVE~|-|2026~|-|109619 path, also the advice for CVE~|-|2026~|-|115560
fatal_error_backtraces ~|=| 0 ; PHP 8.5 only
post_max_size ~|=| 8M ; 32M if your app needs uploads
memory_limit ~|=| ~|-|1 ; CVE~|-|2026~|-|109618: pair with container/cgroup memory limits
Put a limit on request size in front of PHP too, and make sure your WAF inspects large bodies without truncating them. Cloudflare, Fastly, Google, Vercel and AWS WAF have published rules or guidance, but Cloudflare itself stresses that these protections are temporary (BleepingComputer, Wiz).
This week
- Threat hunt back to 17 October using the signals above: shells from web workers, OOM errors, segfaults, new PHP files and unexpected outbound connections from web servers.
- If you find a compromise, rotate everything the web server could read: database credentials in
wp-config.php/env.php/.env, payment-gateway API keys, SMTP credentials and cloud keys. - Track the appliance advisories (Palo Alto Networks, Fortinet, Cisco and others) and patch when fixes ship.
- Keep
session.upload_progress.enabled=0until PHP fixes CVE-2026-115560 in its next regular release (BleepingComputer).
Longer term
- Retire end-of-life PHP. Anything on 7.x or 5.x is permanently exposed to this class of bug.
- Measure patch time for critical internet-facing flaws in hours, not days, as AWS recommends.
- Invest in behaviour-based detections (process lineage, file integrity) that don’t depend on CVE-specific signatures. They catch the next PHP2Shell too.
- Run web workers with minimal privileges and egress filtering, so RCE as
www-datastays contained.
OffensioX perspective
PHP2Shell matters for two reasons beyond its blast radius. First, it sits beneath the application layer: your WAF tuning, plugin hygiene and strong admin passwords don’t change the fact that the interpreter itself parses an attacker’s request. Second, it shows how fast AI is compressing the vulnerability lifecycle. Researchers used frontier models to turn a deeply complex memory bug into reliable RCE, details leaked before the embargo lifted, and attackers were probing honeypots four days before the patch. As AWS put it, “An embargo protects defenders only until someone else finds the same bug.” For businesses in Pakistan and across South Asia, where a large share of e-commerce stores, school and university portals and SME websites run on PHP, often on shared hosting or legacy 7.x stacks nobody remembers to upgrade, the long tail is the real risk. Don’t assume your host has patched. Verify it. If you’d like a second pair of eyes, OffensioX offers penetration testing and web application security assessments that can confirm your exposure and harden what sits in front of it.
References
- Wiz Research: PHP2Shell, critical RCE vulnerabilities in PHP
- AWS Security Blog: Amazon Threat Intelligence identifies PHP2Shell exploitation prior to public disclosure in MadPot
- Datadog Security Labs: PHP2Shell detection, analysis and remediation
- watchTowr: PHP2Shell FAQ
- Help Net Security: PHP2Shell, critical PHP vulnerabilities patched
- BleepingComputer: PHP ships emergency patches for critical PHP2Shell flaws
- BleepingComputer: PHP shares mitigation for new RCE vulnerability with no patch
- The Hacker News: Someone tried to exploit PHP2Shell 4 days before disclosure
- CybelAngel: Internet-facing PHP exposure analysis (Spanish)
- Sansec: PHP2Shell and e-commerce
Comments