PHP maintainers released emergency fixes for two critical flaws, nicknamed PHP2Shell, on October 21 that can let someone with no account and no password take control of a web server by sending it carefully crafted requests. PHP is the software running underneath a large majority of the world's websites: marketing sites, online stores, customer portals, intranets, HR systems, and a great many government services. Because these flaws sit inside PHP itself rather than in any particular website, well-written application code offers no protection; if a server runs an unpatched version of PHP, it is exposed. Attackers did not wait for the announcement: Amazon says someone tried to exploit the flaws against its decoy servers on October 17, four days before any fix existed, and Cloudflare reports attack attempts climbing from thousands to millions within hours of disclosure. Successful attacks can leave almost no trace in normal logs, so a server that was patched on Wednesday may still have been compromised before then. Cyber agencies in the US, UK, and Netherlands are telling organisations to update immediately or take systems offline until they can, and several organisations did exactly that on release day, including HR and payroll provider BambooHR and a long list of Dutch government services.
The flaws, CVE-2026-109618 and CVE-2026-109619, are each rated 9.2 out of 10 under CVSS v4.0. They affect every PHP installation that serves web requests, including Apache with mod_php, PHP-FPM, php-cgi, FrankenPHP, and LiteSpeed, across nearly every PHP release back to 5.4. The fixes are in PHP 8.5.12, 8.4.27, 8.3.36, and 8.2.35. PHP 8.1 and older received no official release, although the PHP security team has published source backports for 7.4, 8.0, and 8.1. The PHP project is clear that configuration changes reduce exposure but do not make a server safe; updating is the only complete fix. Amazon advises investigating suspicious activity back to at least October 17. The sections below cover how the flaws work, which setups carry the most risk, what exploitation looks like so far, how to hunt for it, and what to do in what order.
Why this one matters
Most critical web vulnerabilities live in a specific product: one CMS, one plugin, one framework. PHP2Shell is different because it lives in the engine those products run on. PHP's advisory and the reporting around it make the point plainly: even a single "Hello World" page on a vulnerable PHP version can be attacked, because the vulnerable code runs before or around the application rather than inside it.
That changes the arithmetic for defenders in three ways:
- Application security does not help. A fully patched WordPress, Drupal, Laravel, or custom application running on a vulnerable PHP runtime is still exposed. Updating the application does not update PHP.
- The exposure is enormous. PHP is estimated to power roughly three quarters of all websites. Counts of exposed servers vary with method, from VulnCheck's 2.6 million internet-facing PHP hosts to VirusTotal's 5.1 million, but they agree on the uncomfortable part: most of them are not on a supported version. VulnCheck counts more than 700,000 hosts on PHP 7.3 or older and around 400,000 on 7.4 to 8.1, against roughly 403,000 on the supported 8.2 to 8.5 branches.
- The attacker needs nothing but network access. No account, no user interaction, and on the highest-risk configuration, no particular application behaviour. A successful attack gives code execution as the web server's PHP worker account.
Even short of full takeover, CVE-2026-109619 lets an attacker read memory from the PHP worker process. That memory can hold passwords, session and authentication tokens, API keys, and certificates belonging to other users' requests. The researchers demonstrated this against applications they did not control. The NSA has warned that the flaws could give attackers a direct path to a server's file system or database.
Security researcher Kevin Beaumont called it "one of the biggest vulns in years," and the comparisons to Log4Shell in late 2021 are apt: a flaw in a ubiquitous open-source building block, buried in software that organisations often do not know they are running, with a long tail of systems that will never be patched.
How this came to light
The timeline is unusual, and it explains why defenders had so little notice.
- 2024: During PHP's first external security audit in years, carried out by Quarkslab and funded by Germany's Sovereign Tech Agency, a PHP core developer noticed early signs of the out-of-memory problem behind CVE-2026-109618. An exploit was theorised but no concrete attack path was found, and competing fixes each carried compatibility or stability costs. The PHP Foundation has since described the resulting delay as a structural failure of its decision process and resourcing.
- July to September 2026: Security firm Calif began auditing PHP on July 30. On August 11, Calif researcher Ryan A and OpenAI's Codex Security team independently reported unauthenticated remote code execution from the same root cause. Wiz reported further attack paths on August 24, and OpenAI more on September 18. The researchers say AI models were central to turning a decades-old weakness into a working exploit, compressing what would have been months of team effort into about a week.
- October 17: Amazon Threat Intelligence recorded an attempt to exploit the flaws against its MadPot honeypot network, from an IP address on a commercial anonymisation network. Amazon says it is unclear how the actor obtained exploit information while the flaws were still under embargo.
- October 20, around 15:00 UTC: The two CVE identifiers began circulating on forums and social media, with an incorrect CVSS score of 10.0 and an incorrect date. No technical details leaked at that stage, but watchTowr publicly confirmed the flaws were real.
- October 20, 19:30 UTC: PHP published an advance notice and pulled the release forward by a day to October 21 at 14:00 UTC.
- October 20, around 20:00 UTC: Calif mistakenly posted a video of its proof of concept working against several targets. It was deleted, but copies spread and, according to the PHP Foundation, accelerated public exploit development.
- October 21, around 02:00 UTC: Amazon began seeing multiple proof-of-concept exploits, about 12 hours before the patch, followed by six hours of further attempts from different anonymised infrastructure with varying payloads.
- October 21, 07:41 UTC: Chainguard published container images containing the fix more than six hours before the coordinated release, giving anyone the chance to study the patch while everyone else waited. Threat intelligence firm ELLIO recorded its first PHP2Shell request at 08:36 UTC, less than an hour later.
- October 21, 14:00 UTC: PHP released the fixed versions and its full advisory. The UK NCSC and CISA issued alerts the same day, and the FBI and NSA followed with guidance of their own.
- October 22: Amazon CISO CJ Moses said the flaws are "now being broadly exploited in the wild" and warned defenders not to assume the public disclosure date is the earliest exploitation date.
How the flaws work
Both flaws share a root problem: when a PHP request ends abnormally, PHP can leave its internal memory in an inconsistent state, and a later step trusts that state. Both are classified as use-after-free (CWE-416).
CVE-2026-109618: RCE via out-of-memory corruption
If a request reaches PHP's memory_limit at exactly the wrong moment, for example while PHP is parsing a large multipart form or file upload, PHP can be interrupted while internal request data is only partly set up. The cleanup code that runs afterwards then treats that half-built data as valid and corrupts memory.
On Apache with mod_php, a single unauthenticated request can trigger this before any application code runs, and full remote code execution was demonstrated with default settings. On PHP-FPM, the PHP Foundation says code execution was confirmed through application-level code paths, which means exposure there depends partly on what the application does.
CVE-2026-109619: RCE via stale global state
A fatal error at the wrong point can leave PHP's request-owned internal state pointing at memory that has already been freed. Because PHP workers handle many requests in sequence, the next request processed by the same worker may use that stale pointer before normal initialisation resets it. The result is a use-after-free, memory disclosure across requests, and remote code execution with the worker's privileges.
One confirmed route runs through Session Upload Progress, a PHP feature that tracks file upload progress and is turned on by default, which is why so many default deployments meet the preconditions. On PHP 8.5, the newer fatal error backtrace feature provides another. The reporter demonstrated code execution against a real-world application on mod_php, and the session upload progress path was also validated on PHP-FPM.
Which server setups carry the most risk
| How PHP is run | CVE-2026-109618 | CVE-2026-109619 |
|---|---|---|
| Apache with mod_php | Full unauthenticated RCE demonstrated with default settings, before application code runs | RCE demonstrated against a real-world application |
| PHP-FPM | RCE confirmed through application-level code paths | Session upload progress path validated |
| php-cgi, FrankenPHP, LiteSpeed | Listed as at risk by PHP; less public detail | Listed as at risk by PHP; less public detail |
PHP rates mod_php as the highest-risk configuration, and that is where internet-facing servers should be prioritised. Do not treat any other setup as safe; PHP lists every web-serving configuration as in scope.
Is it being exploited?
Yes, and it started earlier than anyone realised. Reporting on October 22 changed the picture significantly.
- Attacks began before the patch existed. Amazon Threat Intelligence detected an exploitation attempt against its MadPot honeypots on October 17, four days before PHP shipped the fix, from an anonymised IP address. Amazon does not know how the attacker obtained exploit details during the embargo. From around 02:00 UTC on October 21, it saw multiple different proof-of-concept exploits from varied anonymised infrastructure, with payloads that suggest several separate actors.
- The volume is now very large. Cloudflare CEO Matthew Prince says the company saw thousands of attempts in the ten hours before the public announcement, tens of thousands within 45 minutes of it, hundreds of thousands within two hours, and millions after that. Attackers have been adjusting their payloads using feedback from blocked requests to slip past Cloudflare's firewall rules. Pantheon reports blocking more than 60,000 suspicious requests probing for the flaw.
- Many vendors see the same thing. watchTowr, Hadrian, Patchstack, Previdian, and VulnCheck all report attempts, some from before public disclosure. Hadrian describes exploitation "at scale," mostly through the session upload progress path, and VulnCheck has seen automated scanners announcing themselves with the user agent
php2shell-scan/109618. - Amazon now says the flaws are "being broadly exploited in the wild." What no one has yet published is a confirmed compromise of a named organisation, and Amazon says it is unclear whether the attempts it saw would have succeeded against real systems. At the time of writing, neither CVE appears in CISA's Known Exploited Vulnerabilities catalog.
- Code claiming to exploit the flaws is circulating. Some of it does not work and some may be malicious. Do not run unverified proof-of-concept code against your own systems.
The gap between "attempts" and "confirmed breaches" should not be read as reassurance. As the next section explains, a successful attack can leave so little evidence that victims may not know they were hit. We would treat every internet-facing PHP server that was unpatched on or after October 17 as potentially compromised until checked.
When CVE-2024-4577, a PHP-CGI flaw on Windows, became public in June 2024, exploit attempts started within a day, and it was later used in ransomware attacks. PHP2Shell has moved faster than that, with attackers active before disclosure. Amazon's Moses attributes part of the speed to AI-assisted analysis of patches, which is making exploit development cheaper and putting it within reach of more attackers within hours.
Why a breach may be hard to spot
CrowdStrike's analysis highlights the most worrying property of these flaws for defenders: successful exploitation leaves almost nothing behind. There is no login to bypass and no vulnerable page to find, so there is no unusual URL pattern to alert on. The PHP worker stays up, the response comes back as a normal HTTP 200, and application logs show nothing because no application code runs.
The one server-side trace CrowdStrike identified is a single memory-limit fatal error in the web server's error log, the kind of line that is routinely dismissed as noise. Detection therefore depends less on the attack itself and more on what the attacker does next: processes started by PHP, files written to disk, and outbound connections from the web server.
Who is affected
| PHP branch | Vulnerable | Fixed version | Notes |
|---|---|---|---|
| 8.5 | Below 8.5.12 | 8.5.12 | Also set fatal_error_backtraces=0 if you cannot update immediately |
| 8.4 | Below 8.4.27 | 8.4.27 | |
| 8.3 | Below 8.3.36 | 8.3.36 | Security fixes only |
| 8.2 | Below 8.2.35 | 8.2.35 | Reaches end of life on December 31, 2026 |
| 8.1, 8.0, 7.4 | All | No official release | Source backports published by the PHP security team; check your distribution or LTS vendor |
| 7.3 and older, back to 5.4 | Believed affected | None | Upgrade, isolate, or take offline |
A few practical points affect how you read that table:
- Distribution packages can carry the fix under an older-looking version number. Linux distributions and LTS vendors received the patch in advance and may backport it without changing the upstream version string. Check the package changelog for the CVE identifiers, not the version.
- The volunteer-run
rpms.remirepo.netrepository did not have updates on release day. PHP recommends switching to distribution packages or building from source if you depend on it. - Hosting platforms are catching up. CloudLinux has released fixed packages for its
ea-php(5.2 through 8.5) andalt-phpbuilds, which covers many cPanel-based hosts. If you are on shared or managed hosting, confirm with your provider rather than assuming. - PHP hides in places patch management often misses: control panels such as cPanel and Plesk, vendor appliances, Windows software that bundles PHP, container base images, and long-forgotten internal tools.
What you should do
1. Find every PHP installation that serves web traffic
Inventory PHP across servers, containers, appliances, and hosting accounts, and note how each one is run (mod_php, PHP-FPM, CGI, FrankenPHP, or LiteSpeed). Check the PHP that actually serves web requests, not the command-line PHP, which can be a different version and configuration. Useful starting points:
# Which PHP SAPI and modules Apache is loading
apachectl -M 2>/dev/null | grep -i php
# PHP-FPM version
php-fpm -v # or php-fpm8.x -v, depending on packaging
# Check whether your distribution package contains the fix (Debian/Ubuntu)
apt changelog php8.2-fpm | grep -E "CVE-2026-10961[89]"
# Check whether your distribution package contains the fix (RHEL family)
rpm -q --changelog php-fpm | grep -E "CVE-2026-10961[89]"
Prioritise internet-facing servers using mod_php, then everything else internet-facing, then internal systems. OpenAI has also published a Codex skill, php2shell-checker, for testing whether a site or PHP binary is vulnerable; as with any tool, use it only against systems you are authorised to test.
2. Update the PHP runtime and restart every worker
Update to 8.5.12, 8.4.27, 8.3.36, or 8.2.35, or install your distribution's or LTS vendor's patched package. Then restart Apache, PHP-FPM, and any long-running PHP workers; a patched binary does nothing for processes still running the old code. Rebuild and redeploy container images rather than assuming a base image has been refreshed.
If someone else runs your PHP, such as a managed host, shared hosting provider, or SaaS vendor, ask them directly when patched PHP will be in place, and get the answer in writing for anything that handles sensitive data.
3. If you cannot update immediately, reduce exposure
The UK NCSC and CISA both advise that systems which cannot be patched should be taken offline or removed from public access. Short of that, put the site behind a VPN, client allowlists, or authenticated access at the edge, and confirm that the origin server cannot be reached directly around those controls.
PHP's advisory lists configuration changes that block known attack paths but do not make an installation safe:
; CVE-2026-109619: set in php.ini, an FPM pool, or server config, then restart every worker
session.upload_progress.enabled = 0
; PHP 8.5 only
fatal_error_backtraces = 0
; CVE-2026-109618: set so applications cannot override it (for example php_admin_value)
memory_limit = -1
; 8M if the application does not accept uploads, 32M if it does
post_max_size = 8M
Important caveats from the advisory:
- Do not rely on
ini_set()or a PHP-FPM.user.inifile for the session setting; it must apply before PHP parses the request. - With
memory_limit = -1, use a container or cgroup memory limit as the safety net, preferably one that kills only the affected worker. Do not useRLIMIT_ASorRLIMIT_DATAinstead, as they can trigger the vulnerable code path. - Enforce request-size, field-count, multipart-part, header-count, and nesting limits at the web server or reverse proxy, including for requests without a usable
Content-Length. - Remove invalid or deprecated per-request settings that emit diagnostics early. Suppressing errors with
error_reporting,display_errors, or@does not help.
Web application firewalls are a stopgap. Cloudflare has deployed free rules for all customers, which is worth having, but they only cover traffic that passes through Cloudflare, and attackers have already been seen adjusting payloads to evade them.
4. Review memory settings after updating
The fix introduces a new hard memory limit. When a process reaches it, the process ends and shutdown handlers do not run. Check memory_limit and post_max_size against what each application genuinely needs, and watch for new worker terminations after the upgrade.
5. Hunt for compromise back to October 17
Patching closes the door; it does not tell you whether someone already came through it. Amazon advises looking back to at least October 17. Because a successful attack can return a normal response and leave application logs empty, focus on the web server, the PHP processes, and the host:
- Memory-limit fatal errors ("Allowed memory size ... exhausted") in web server or PHP error logs, especially single occurrences that coincide with multipart POST requests. CrowdStrike notes this may be the only server-side trace of a successful attack.
- Unusual multipart requests followed by memory-limit errors or repeated HTTP 500 responses
- Unusually large
PHPSESSIDcookies in responses - Unexplained restarts or crashes of PHP workers
- PHP processes (
php-fpm,php-cgi,httpd,apache2) starting shells, interpreters, or download tools such ascurlandwget; the FBI specifically recommends monitoring for PHP processes unexpectedly launching command shells or downloading files - Outbound connections from web servers to unfamiliar destinations
- New or modified files in the web root, new cron jobs or scheduled tasks, and new user accounts
A quick first pass on a Linux web server:
# Memory-limit fatals since October 17 (adjust paths for your distribution)
grep -h "Allowed memory size" /var/log/apache2/error.log* /var/log/httpd/error_log* \
/var/log/php*-fpm.log* 2>/dev/null
# Requests from the known PHP2Shell scanner user agent
grep -h "php2shell-scan" /var/log/apache2/access.log* /var/log/httpd/access_log* \
/var/log/nginx/access.log* 2>/dev/null
# Files in the web root changed since October 17
find /var/www -newermt "2026-10-17" -type f -name "*.php" 2>/dev/null
Amazon and VulnCheck have published source addresses seen attempting exploitation. They are worth searching for in firewall, WAF, and access logs, but treat them as low-confidence indicators: most belong to anonymisation services and VPNs, they will change quickly, and a match shows an attempt rather than a compromise.
| Source | Observed | IP addresses |
|---|---|---|
| Amazon (pre-disclosure, October 17) | MadPot honeypot attempt from an anonymisation network | 103.216.220.92 |
| Amazon (October 21) | Proof-of-concept exploit attempts | 31.223.184.166, 37.19.200.5, 134.209.159.64, 103.114.163.188, 95.217.98.37 |
| VulnCheck | Honeypot attempts, user agent php2shell-scan/109618 |
85.11.167.243, 45.198.224.169 |
| VulnCheck | Attempts against both CVEs | 109.71.252.97 |
If you find something, isolate the server and preserve web server, PHP, and system logs before cleaning up. Do not simply patch over a server that shows signs of compromise; a patch removes the way in, not anything the attacker left behind.
6. Consider rotating secrets on exposed servers
Because CVE-2026-109619 can leak worker memory without full code execution, any internet-facing PHP server that sat unpatched from October 17 onward may have exposed credentials it handled. For high-value applications, consider rotating database passwords, API keys, and signing secrets, and invalidating active sessions, once the server is patched.
7. Plan your way off end-of-life PHP
Backports and vendor patches buy time, but PHP 8.1 and older will keep accumulating unfixed flaws, and PHP 8.2 reaches end of life on December 31, 2026. If this week has revealed systems that nobody was tracking, that is the more important finding.
A note on the pattern
PHP2Shell joins a growing family of vulnerabilities with "Shell" in the name, from Shellshock and Log4Shell to this year's string of "2Shell" disclosures. The naming signals the same thing each time: untrusted input from the network ends in an attacker controlling a shell on the server. What these flaws share is that they sit in components so deep and so widespread that most organisations cannot say with confidence where they are running.
PHP2Shell adds two newer themes. The first is speed. The researchers and the PHP Foundation both credit AI-assisted tooling with turning a weakness first noticed in 2024 into a reliable exploit, and Amazon's CISO credits the same kind of tooling for how quickly attackers moved once patches and clues appeared. Someone was already attempting exploitation four days before disclosure. The time between "a flaw exists" and "a working exploit exists" is shrinking, coordinated disclosure is getting harder to hold together, and defenders can no longer treat the public announcement date as the start of the danger window.
The second is the fragility of the open-source foundations that commercial software depends on. The PHP Foundation was candid that a small team, short of resources, struggled for months to agree on a fix for a problem in code that runs a large share of the web. Every organisation that relies on PHP benefits from that work; very few contribute to it.
The defensive lesson is not new, but it is sharper. Know what runtimes and libraries your systems actually depend on, including the ones bundled inside products you did not build. Keep them on supported versions. And have a tested way to restrict, isolate, or switch off an internet-facing service quickly, because for flaws like this one, that capability is what stands between an emergency patch day and an incident.
Summary
| Name | PHP2Shell |
| CVEs | CVE-2026-109618 (RCE via out-of-memory corruption), CVE-2026-109619 (RCE via stale global state) |
| Component | PHP engine (memory management and error handling) |
| Type | Use-after-free (CWE-416) |
| CVSS | 9.2 (Critical, CVSS v4.0) for each |
| Impact | Unauthenticated remote code execution as the PHP worker account; cross-request memory disclosure of credentials and tokens |
| Affected | All PHP installations serving web requests (mod_php, PHP-FPM, php-cgi, FrankenPHP, LiteSpeed), nearly every version back to PHP 5.4 |
| Highest risk | Apache with mod_php, where an attack can succeed before any application code runs |
| Disclosed | October 21, 2026, a day early after an October 20 leak (PHP advisory, GHSA-w8hw-w9fx-j79w, GHSA-6wmf-4rv5-p3rp) |
| Discovered by | Calif, OpenAI Codex Security, and Wiz Research |
| Exploited in the wild? | Yes. Attempts from October 17, four days before the patch (Amazon); millions of attempts since disclosure (Cloudflare); Amazon says "broadly exploited." No named victim publicly confirmed at time of writing |
| CISA KEV? | Not at time of writing |
| Look-back window | Investigate from at least October 17, 2026 |
| Workaround | None complete. Isolate or take offline if unpatchable; session.upload_progress.enabled=0, fatal_error_backtraces=0 (8.5), memory_limit=-1 with a container or cgroup limit, and a low post_max_size reduce exposure |
| Detection | Isolated memory-limit fatal errors in web server logs, multipart requests followed by memory-limit errors or HTTP 500s, oversized PHPSESSID cookies, unexplained worker restarts, PHP processes spawning shells or download tools, php2shell-scan user agent; successful attacks may otherwise return HTTP 200 and leave application logs empty |
| Full fix | PHP 8.5.12, 8.4.27, 8.3.36, or 8.2.35 (or a vendor backport), followed by restarting every PHP worker |
A flaw in the engine beneath most of the web, attacked before it was disclosed, now targeted by the millions, quiet when it succeeds, and with no complete workaround: this is a patch-now event, followed immediately by a hunt. Find every PHP runtime you own or depend on, update and restart it, isolate whatever cannot be updated, and check every server that was exposed from October 17 onward.
If you need help finding where PHP is hiding in your environment, prioritising what to patch first, or checking whether anything got in before you did, get in touch. The flaws that matter most are often in the software nobody remembers is there.