What happened
On October 21, 2026, the PHP security team released 8.5.12, 8.4.27, 8.3.36 and 8.2.35 to fix two flaws nicknamed 'php2shell' (CVE-2026-109618 and CVE-2026-109619), both scored 9.2 under CVSS 4.0. Each lets a stranger run code on the server with a single HTTP request, no account needed. The login page makes no difference: PHP handles the booby-trapped request before a single line of the application runs.
The first comes from the way PHP enforces its memory limit. When a request goes over it, in the middle of parsing a file upload form for instance, PHP stops dead and leaves half-built data behind, which the cleanup routine then treats as valid. The second lets one request's state outlive the memory it pointed to: the next request served by the same process, another visitor's, can land on it. Upload progress tracking, on by default, is enough to reach it.
Everything that serves PHP on the web is in scope: mod_php under Apache, PHP-FPM, php-cgi, FrankenPHP, LiteSpeed. The faulty code path goes back to PHP 5.4, released in 2012, and the 8.1 and older branches only got source patches, no release. Researchers at Calif confirmed unauthenticated code execution against versions of WordPress, Drupal, Joomla and Magento. PHP runs about 69% of the websites whose server-side language is known.
The timeline ran away. Amazon's honeypots saw a first exploitation attempt on October 17, four days before disclosure. The CVE identifiers leaked on the 20th, and PHP moved its release up a day. On the 21st, Amazon, Cloudflare and watchTowr were reporting exploitation attempts from several actors; the PHP Foundation, for its part, had found no working public exploit at release time. PHP's team did its job fast and well. This piece is not aimed at them.
Why we had nothing to patch
First, because none of our products is written in PHP. What the Lab runs, its own products and the platforms it builds for clients, is Elixir on Erlang's virtual machine, the BEAM; we explained why in an earlier post. So on Wednesday there was no php.ini to harden and no server to restart in a hurry.
There is also a deeper reason, which should not be overstated. The second flaw lives on state that carries over from one request to the next in the same process. On the BEAM, each connection is served by its own lightweight process, with its own memory, handed back when it ends: no process keeps what the previous visitor left behind. And a process that crashes dies alone instead of carrying on with damaged state. That class of bug is much harder to write there.
Harder, not impossible. The BEAM is written in C, like PHP, and our ecosystem has had its own critical flaw: in April 2025, Erlang/OTP's SSH server allowed code execution without authentication (CVE-2025-32433, scored 10). Our applications do not start that server, but the lesson holds: the language we chose spared us this one; it will not spare us the next.
What actually protects us: upgrading often
A flaw is fixed by an upgrade, so everything comes down to how far you are from the fixed version. If you are current, it is a version number and a restart. If you are three years behind, it is a migration, with its regressions, and it lands on the day an exploit is going around. Sites still on PHP 8.1 are finding that out this week: there is no fixed release for them.
So we move our dependencies continuously, in small steps. In five months, the file that pins the dependency versions of our CMS and the sites it serves has changed 24 times. Each upgrade is small, and therefore uneventful.
And we look. Recently, the Elixir ecosystem's audit flagged 45 security advisories across 12 of our packages, nine of them rated high, among them an XSS flaw in the magic-link sign-in forms of our authentication library. Every upgrade fit within our version constraints: new version numbers, nothing rewritten. A few weeks later, new critical advisories on the same library, among them replayable magic links and a revoked session still accepted: same treatment, same calm.
That check does not depend on us remembering. Every change goes through a dependency audit and a static security analysis, and the build fails if either finds something. Once a month the same audit runs with no change to trigger it, to catch advisories published between two releases, and a probe checks the encryption and security headers of the platforms we host.
Nothing heroic about it. It is a routine, and the routine is what turns a critical flaw into an ordinary Tuesday.
If you run PHP in production
Upgrade today: 8.5.12, 8.4.27, 8.3.36 or 8.2.35. Inventory the PHP that serves the web, not the command-line one, which may be another version, and do not forget containers and products that ship their own interpreter. The Dutch NCSC keeps a list of affected products.
If you cannot upgrade right away, CERT-EU recommends three settings, made by the administrator so the application cannot override them: in the PHP-FPM pool, or with the same directives in the Apache configuration for mod_php.
; PHP-FPM pool — not ini_set(), not .user.ini
php_admin_value[memory_limit] = -1
php_admin_flag[session.upload_progress.enabled] = off
; PHP 8.5 only
php_admin_flag[fatal_error_backtraces] = off
Offset memory_limit = -1 with a memory limit on the container, then restart every worker. These are stopgaps: Datadog points out that the setting blocks the known exploitation path, not the underlying defect.
And if upgrading is impossible because the application only runs on an old version, that is the real issue, and it did not start this week. It is the kind of work we take on: picking up an application nobody dares touch any more and putting it back on a footing you can upgrade on a Tuesday. Talk to us.
Sources · read on October 22, 2026
- CERT-EU — Critical Vulnerabilities in PHP, advisory 2026-018 (new tab) cert.europa.eu/publications/security-advisories/2026-018
- Datadog Security Labs — PHP2Shell: detection, analysis, and remediation (new tab) securitylabs.datadoghq.com/articles/php2shell-critical-vulnerabilities-in-php
- Tenable — php2shell: frequently asked questions (new tab) tenable.com/blog/php2shell-cve-2026-109618-cve-2026-109619-frequently-asked-questions-about-critical-php-remote
- NCSC-NL — List of affected products (new tab) github.com/NCSC-NL/php2shell