Today, 21 October 2026, the PHP project shipped fixes for two critical flaws in the PHP runtime itself: CVE-2026-109618 and CVE-2026-109619, together called PHP2Shell. Both let an unauthenticated attacker run code on your server over HTTP before a single line of your application runs. The earliest affected code shipped in PHP 5.4.0 in 2012. OpenAI calls it “one of the most impactful security issues in recent memory”, and with PHP running 69.3% of websites whose server-side language is known (W3Techs), almost 70% of the web is in scope.
The security firm Calif found the flaws using OpenAI’s GPT-5.6 Sol, as part of OpenAI’s Patch the Planet initiative; Wiz Research found them independently. That is the real story: a class of bug humans circled for 22 years became validated remote code execution in weeks. This post covers why it took AI, how AI is helping fix it, and what PHP and Laravel teams have to do today.
The short version: update PHP to 8.5.12, 8.4.27, 8.3.36 or 8.2.35, then restart every PHP worker.
What PHP2Shell is
Both flaws are rated critical at CVSS v4.0 9.2 (watchTowr rates it 10.0), and both are use-after-free bugs (CWE-416):
- CVE-2026-109618, RCE via OOM corruption. PHP handles out-of-memory errors with
longjmp(). If memory runs out while internal request data is only partly initialized, request cleanup treats that invalid data as valid. The attack paths run through multipart/form-data parsing, which PHP does before your code runs. Full RCE was validated over HTTP against mod_php with default input and memory limits. - CVE-2026-109619, RCE via stale global state. Request-owned internal state survives after its memory is freed, for example after a fatal error or an out-of-memory error. A later request on the same worker reads that stale state before initialization resets it: a cross-request use-after-free. It was confirmed through PHP 8.5’s
fatal_error_backtracesand through session upload progress, which is on by default, against mod_php and FPM.
The result is code execution as the web-worker user, plus disclosure of memory that can hold passwords, session tokens and keys. Because it happens before your application starts, clean application code does not protect you; as Cloudflare puts it, “updating website code or a plugin alone does not fix these vulnerabilities”. PHP-FPM, Apache mod_php (the highest risk, with a demonstrated exploit), php-cgi, FrankenPHP, LiteSpeed/LSAPI and PHP on Windows are all affected, and so is any Docker image with an old PHP. Sansec confirmed pre-auth RCE on Magento, WordPress, Drupal, Joomla, MediaWiki, Roundcube, phpMyAdmin, Nextcloud, Laravel 13.11, Symfony 8.1 and WHMCS.
Why it took AI to find it
PHP is one of the most-reviewed C codebases on earth, and this bug still sat in it for about 14 years. The reason is where it lives: on an error path. Exploitation needs an out-of-memory longjmp() in the middle of initialization, combined with state that survives across requests on a reused worker. Human code review rarely reasons through combinations like that, and plain fuzzing rarely reaches them.
People did circle this class of bug for 22 years, without proving it exploitable:
- 2004: Stefan Esser described the first remote PHP memory-limit vulnerability.
- 2020: PHP bug #78876 showed out-of-memory errors leaving temp files behind on multipart input.
- 2024: the OSTIF/Quarkslab audit of PHP found a related out-of-memory issue, but exploitation stayed “unproven”.
With frontier models, the same ground was covered in weeks. Calif started on 1 August 2026 with GPT-5.6 Sol and sent its first report to PHP on 11 August. Wiz reproduced the RCE independently using LLMs and reported on 24 August; one of its researchers built a working exploit in about a week. Sansec credits frontier AI models with making the exploits practical. Wiz’s verdict: “These findings rank among the most severe vulnerabilities discovered in PHP, and arguably in software history.”
Nor is it a one-off. In July, Searchlight Cyber used the same model to find wp2shell, a pre-auth RCE chain in WordPress core, in just over 10 hours and for a trivial compute bill. OpenAI says the PHP flaws “are among several significant vulnerabilities” it has found, and it expects “similar findings to increase sharply”.
Attackers have the same models
This capability is not reserved for defenders, and PHP2Shell proved it. Details leaked on Hacker News on 20 October, a day before the fixed releases; watchTowr confirmed the bug the same day, and PHP pre-announced the release. Cloudflare saw early attacks before the patch shipped, and Sansec expected mass exploitation within minutes of release. When a flaw can go from a model’s finding to a working exploit in a week, defenders cannot opt out: AI-assisted review is now table stakes, not a nice-to-have.
How AI is helping fix it
Finding a bug is half the work. OpenAI frames Patch the Planet around two further steps: “validate and fix the upstream vulnerability” and “give affected organizations time to act”. For PHP2Shell that meant:
- Two months of coordinated remediation between Calif, Wiz, OpenAI, Quarkslab and the PHP team, with Linux distributions and LTS vendors receiving patches in advance. The GitHub advisories credit reporters from Calif, Wiz, Areion and OpenAI, and according to heise, OpenAI also helped review the fix.
- A fix that removes the root cause: PHP no longer uses
longjmp()on out-of-memory errors. It records a delayed “soft” OOM, then exits hard with_exit(). - Edge protection before the release: Cloudflare switched on WAF rules by default for free and paid plans at 03:02 UTC on 21 October, about 11 hours before the fixed releases shipped at 14:00 UTC.
- Tooling for maintainers: OpenAI’s Codex Security, launched in March 2026, finds and validates vulnerabilities, proposes fixes, and is free for open-source maintainers.
The lesson for everyone else: discovery is worthless without validated findings, coordinated fixes and operators who actually update. That last step is yours.
What to do today
Update PHP and restart every worker
Update to PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35, which PHP calls “the only complete mitigation”. Use your distribution’s or hosting provider’s packages, or build from source; the Remi repository had no packages on release day. Then restart every PHP worker (FPM pools, Apache): an updated package does nothing for processes that are already running.
# confirm the CLI and the FPM binary both report a fixed release
php -v
php-fpm8.4 -v
# restart every worker (service names vary by distribution)
sudo systemctl restart php8.4-fpm
sudo systemctl restart apache2End-of-life PHP versions
PHP 7.4, 8.0 and 8.1 are end of life. php-src has minimal source backport branches for them but no official binaries, so you need a vendor backport, a build from source or an upgrade. PHP 5.x through 7.3 get nothing: upgrade, take the service offline, or put it behind a VPN or WAF. PHP 8.2 reaches end of life on 31 December 2026, so plan that upgrade now too. This is not a niche: per W3Techs, 27.0% of PHP sites run PHP 7 and 7.7% run PHP 5, so roughly a third of PHP sites are on a version with no official fixed release.
Inventory every PHP runtime
List every PHP install, not just your main application servers: control panels, vendor appliances, CMS hosts, Docker base images and CI images. If that list does not exist yet, building it is the first task. Keeping it current, together with the pipeline that ships patches, is everyday work in our DevOps and cloud practice.
Laravel: Composer will not fix this
Sansec confirmed Laravel 13.11 as exploitable. composer update does not help, because the flaw is in the runtime, not in a package. Check the PHP version on every server, queue worker and image: Sail, Forge servers, Vapor and Lambda runtimes, and Laravel Cloud. Octane and FrankenPHP keep long-lived workers, so make sure they are restarted after the update.
If you cannot patch right now
PHP lists interim mitigations and calls them “a temporary crutch”. Use them only to buy time:
- Set
memory_limit=-1viaphp_admin_value. Be aware that a single request can then use all of the server’s memory. - Lower
post_max_size: 8M without uploads, 32M with uploads. - Set
session.upload_progress.enabled=0in php.ini or the FPM pool, not viaini_set()or .user.ini. PHP suggests keeping it off even after patching. - On PHP 8.5, set
fatal_error_backtraces=0. - Lower
max_input_nesting_level. - Block multipart/form-data at the edge if you do not need uploads.
- Do not use RLIMIT_AS or RLIMIT_DATA.
- Restart workers after any of these changes. Cloudflare’s WAF rules add temporary protection on top.
In an FPM pool, the first three look like this:
; FPM pool (e.g. www.conf): interim only, update PHP as soon as you can
php_admin_value[memory_limit] = -1
php_admin_value[post_max_size] = 8M
php_admin_flag[session.upload_progress.enabled] = offWatch for signs of exploitation
- Multipart requests followed by memory-limit errors or HTTP 500s.
- Oversized or malformed PHPSESSID cookies.
- Unexplained worker restarts.
- PHP workers spawning shells, curl or wget.
If you see signs of compromise, isolate the host, preserve the logs, and look for webshells, new files in the web root, new cron jobs and new accounts.
What this means for your own code
Patch the runtime now. Then assume that models like the one behind PHP2Shell will be pointed at your application, your dependencies and your infrastructure, because attackers will point them there. Get there first: run AI-assisted review on your own code, with experienced engineers validating every finding and fixing what is real. A model’s output is a lead, not a verdict, and shipping AI output nobody reviewed is how new holes get made.
That is how our security audits work: senior engineers who use AI tooling to find and validate issues across application code, dependencies and infrastructure, rank them by real risk, and then fix them with you. For the detection and triage side, see our security use cases. If you want to know where your PHP and Laravel stack stands after PHP2Shell, tell us about your setup and we will come back with what to fix first.
Sources
- PHP: security releases announcement, 21 October 2026
- php-src security advisory GHSA-w8hw-w9fx-j79w (CVE-2026-109618)
- php-src security advisory GHSA-6wmf-4rv5-p3rp (CVE-2026-109619)
- OpenAI: coordinated disclosure of critical vulnerabilities
- Sansec: PHP2Shell research
- Cloudflare: WAF protection for the PHP vulnerabilities
- Huntress: PHP2Shell, leaked critical PHP vulnerabilities
- W3Techs: usage statistics of PHP
