PHP2Shell (CVE-2026-109618, CVE-2026-109619): What It Is and How to Check and Fix Your Server
newsUpdated 14 min read
PHP2Shell (CVE-2026-109618 and CVE-2026-109619) lets attackers run code on unpatched PHP servers. What it is, who is at risk, and how to check and fix it.

Developing story. Last verified: 2026-10-22. Vendors are still shipping fixes, so treat the linked advisories as the latest word on versions.
By Frankie C. · Senior Market Researcher, Mindber. Tracks 500+ AI/SaaS tools across SEA markets via the Mindber Innovation Index methodology.
How we assessed this: On 22 October 2026 we read the PHP advisories GHSA-w8hw-w9fx-j79w and GHSA-6wmf-4rv5-p3rp, the php.net announcements and Cloudflare's write-up. The FrankenPHP release notes and the NCSC-NL php2shell repository filled in the rest. Mindber did not run an exploit or test any server. The commands are standard administration commands, matched to what the advisories ask you to check.
If your site runs on PHP, Wednesday's security release needs your attention today. Two flaws in the PHP engine, CVE-2026-109618 and CVE-2026-109619, together nicknamed PHP2Shell, let an attacker run code on a web server without logging in. They sit below WordPress, Magento and Laravel, so no plugin or framework update reaches them. The fix is a new PHP build, and then a restart of the workers that run it.
Our view: treat any server running Apache with mod_php as an emergency. That is where the PHP team proved a complete attack that needs nothing from your application. PHP-FPM sites are harder to hit, but one variant was proven against FPM too, so they belong in tonight's patch run, not next week's maintenance window.
What to do now
Find your branch in this table and get to its fixed release, or to your Linux vendor's package that carries the same patch.
| PHP branch | Fixed release | Notes |
|---|---|---|
| 8.5 | 8.5.12 | Until patched, also set fatal_error_backtraces=0 |
| 8.4 | 8.4.27 | |
| 8.3 | 8.3.36 | |
| 8.2 | 8.2.35 | End of life on 31 December 2026 |
| 8.1, 8.0, 7.4 | No official release | Minimal source backports on php-src branches such as PHP-8.1-CVE-2026-109618-109619, or a distro or LTS vendor package |
| 8.6 (testing) | 8.6.0 RC4 | Not for production |
| 5.x | None | Move to a supported branch |
Then work through four moves, in this order:
- Find out which PHP build serves your site, and whether Apache runs it as mod_php. A mod_php server goes first.
- Install the fixed build. On Debian, Ubuntu or RHEL the patched package may keep an older-looking number, so check its changelog for the CVE.
- Restart every PHP worker and confirm the running version. Until then, the old code is still in memory.
- If something stops you patching today, apply the stopgap settings below and keep your WAF on until you can.
On shared hosting the first three moves belong to your host, so ask them in writing whether PHP has been updated and the workers restarted. The commands for each move are in the patch section further down.
How the two bugs work
CVE-2026-109618: running out of memory at the wrong moment
Every PHP request gets a memory budget, the memory_limit setting. Normally, when a request goes over it, PHP stops that request and cleans up. The trouble is how it stops: it jumps straight out of whatever it was doing, using a C function called longjmp(). If that jump happens while some code holds request memory it has only half set up, the cleanup routine later reads that memory as if it were complete. An attacker who shapes the heap carefully can turn that misread into code execution.
The allocation that fails doesn't even need to be related to the half-built data. Any allocation failing at the wrong moment will do, which is why the attacker's real job is to make PHP run out of memory on cue. The advisory for CVE-2026-109618 lists three ways, all through ordinary multipart form posts:
- A multipart request without a usable
Content-Lengthpasses the firstpost_max_sizecheck and keeps sending data. - One form part can carry any number of headers, and PHP stores them in far more memory than they take on the wire.
- Empty file fields don't count toward
max_file_uploads, yet each still builds metadata arrays, and nested field names multiply the work.
Where the parsing happens decides how bad this is. Apache with mod_php parses the request body before your application starts, so a site with no upload form at all is still exposed. The PHP team validated full remote code execution over HTTP against mod_php with default memory and input limits and a normal multi-worker prefork setup. PHP-FPM ends a worker whose request startup fails, which closes that early path. An attacker there needs an application route that runs out of memory later, such as an import job that builds a huge array from user input. The advisory still calls FPM susceptible, though nobody had shown a complete FPM exploit for this bug. FrankenPHP calls the cleanup routine the way mod_php does, and the advisory rates it likely susceptible.
CVE-2026-109619: leftovers from the previous request
A PHP worker is a long-running process that serves one request, tidies up, and then serves the next. Some of what it keeps between requests is global state: error details, session data, extension data. While a request runs, parts of that state point into memory that belongs to the request. At the end, PHP is meant to reset those pointers before it frees the memory.
A fatal error can interrupt that tidy-up. The request dies, its memory is freed, and the global state still points at it. When the same worker picks up the next request, some code runs before PHP resets that state, reads the stale pointer and touches memory that now belongs to nothing. That is a use-after-free, and with a prepared heap it becomes code execution. An attacker therefore needs two requests to the same worker: one that leaves the stale pointer behind and one that trips over it.
The advisory for CVE-2026-109619 confirms two ways the second request can trip:
- A warning raised while PHP applies per-request settings. A deprecated directive in
.htaccessdoes it, and so does a bad value that nginx passes throughPHP_VALUE. - Session upload progress. It is on by default and runs before normal session setup, even if your code never calls
session_start().
On PHP 8.5 with fatal_error_backtraces enabled, every fatal error leaves backtrace state behind, and that gave the strongest confirmed exploit against mod_php. The session path worked against mod_php and against a normal dynamic FPM pool. Hiding errors changes nothing, because PHP touches the stale state before it decides whether to show or log a warning. error_reporting, display_errors and the @ operator all come too late.
Which servers are most at risk
php.net scopes the problem to every PHP installation that serves web requests. How PHP connects to the web server decides how exposed you are:
| Setup | What the advisories show | First move |
|---|---|---|
| Apache with mod_php | Remote code execution confirmed, before your app runs | Patch today, then restart Apache |
| nginx or Apache with PHP-FPM | Confirmed through session upload progress when an app route can be made to fail. The out-of-memory path is rated susceptible, not demonstrated | Patch, restart FPM, check PHP_VALUE lines in the proxy config |
| FrankenPHP | Rated likely susceptible, no exploit shown | Move to FrankenPHP 1.13.2 |
| LiteSpeed (LSAPI) | Rated likely for app-specific paths, not validated | Install your vendor's patched PHP build |
| Docker | Same as the PHP version inside the image | Rebuild on a fixed tag such as php:8.3.36-apache |
| Shared hosting | Same as the PHP your host runs | Check the PHP version in your panel and ask the host |
| Appliances that bundle PHP | Several listed as vulnerable by NCSC-NL, others still under investigation | Watch the vendor advisory and limit admin access |
To see what that means in practice, take a hypothetical case built on the path the advisory confirms. A small WooCommerce shop runs on a VPS with Apache, mod_php and PHP 8.3.30. An attacker sends crafted multipart POST requests to the home page, again and again. PHP parses each body before WordPress loads, runs out of memory at the bad moment and corrupts its own heap during cleanup. Extra workers and normal traffic mean more attempts, yet the advisory says they don't remove the condition. Once an attempt lands, the attacker runs commands as the web user, often www-data, and wp-config.php with its database password is one file read away. Customer records and payment plugin keys sit right next to it.
Move the same shop to PHP-FPM and the attack gets harder. The attacker now needs an app route that leaves stale state behind and a second request that reaches the same worker. Harder is not safe, though: the session variant was proven on exactly that kind of pool.
Appliances are the awkward case. NCSC-NL keeps a running list of products that bundle PHP. When we checked, it marked QNAP QTS, Palo Alto PAN-OS and Panorama, Citrix NetScaler ADC and Check Point firewall web interfaces as vulnerable, and pfSense and OPNsense as fixed. QNAP's advisory QSA-26-18 lists QTS 6.1.0 and QTS 5.2.11 and earlier, with fixes still to come. Firewalls, NAS boxes, building systems and admin panels often run PHP you can't update yourself. Keep their admin pages off the open internet until the vendor ships a fix.
Patch and verify your server
The commands assume a Linux server with shell access. Swap 8.3 for your own branch. Order matters.
Step 1: find the PHP build your site runs
The command-line PHP and the web PHP can be different builds, so check both, and check how Apache loads PHP.
step-1-find-php.sh
php -v # command-line PHP
php-fpm8.3 -v # Debian / Ubuntu FPM
php-fpm -v # RHEL, AlmaLinux, Rocky FPM
apachectl -M 2>/dev/null | grep -i php # php_module here means mod_phpDistribution packages often keep the old upstream number and backport the fix. Ubuntu 24.04's PHP 8.3 package, for instance, reports 8.3.6. Search the changelog instead of trusting the number:
step-1b-check-backport.sh
# Debian / Ubuntu
dpkg -l | grep -E 'php[0-9.]*-(common|fpm|cli)|libapache2-mod-php'
apt changelog php8.3-common | grep -m1 -E 'CVE-2026-10961[89]'
# RHEL, AlmaLinux, Rocky
rpm -q --changelog php-common | grep -m1 -E 'CVE-2026-10961[89]'A match means the installed package carries the fix. From outside, curl -sI https://example.com | grep -i x-powered-by shows the version a site advertises, and OpenAI's open-source php2shell-checker runs the same test. A missing header proves nothing, and the checker's README warns that an UNKNOWN result does not mean patched.
Step 2: install the fix
step-2-update-php.sh
# Debian / Ubuntu: upgrade every installed PHP package
sudo apt update
sudo apt install --only-upgrade $(dpkg -l | awk '/^ii/ && $2 ~ /php/ {print $2}')
# RHEL, AlmaLinux, Rocky
sudo dnf upgrade --refresh 'php*'
# Docker: rebuild on a fixed tag, for example php:8.3.36-apache
docker build --pull -t my-app .PHP from a third-party repository, such as the ondrej/php PPA or Remi, updates from that repository, so confirm it has published the fixed build. FrankenPHP 1.13.2 bundles the fixed PHP in its Docker images and static binaries, and also fixes four bugs in FrankenPHP itself. On Windows, php.net has fixed binaries on its downloads page. On cPanel EasyApache 4 servers that can't update yet, NCSC-NL publishes a partial mitigation script.
Step 3: restart every worker and confirm
step-3-restart.sh
sudo systemctl restart php8.3-fpm # PHP-FPM
sudo systemctl restart apache2 # mod_php on Debian / Ubuntu
sudo systemctl restart httpd # mod_php on RHEL familyRun Step 1 again afterwards. If the site starts crashing with zend_mm_heap corrupted, you have probably hit the one known regression. Two of the fixed releases can crash when garbage collection meets a SimpleXMLElement whose properties were read. It is php-src issue #24488, since closed as fixed. Rolling back to dodge it reopens PHP2Shell, so stay on the patched build and take the next point release.
Step 4: if you can't patch today
php.net lists stopgaps that reduce exposure without making a server safe. Put them in php.ini, an FPM pool or the Apache config, never in ini_set() or an FPM .user.ini, and restart every worker afterwards.
php2shell-stopgap.ini
; CVE-2026-109619
session.upload_progress.enabled = 0
fatal_error_backtraces = 0 ; PHP 8.5 only
; CVE-2026-109618
memory_limit = -1 ; set with php_admin_value so apps can't override it
post_max_size = 8M ; 32M if you need file uploadsEach line has a cost. With memory_limit=-1, one runaway request can eat the server's RAM, so add a container or cgroup memory cap that kills only the worker. Avoid RLIMIT_AS and RLIMIT_DATA, which the advisory says trigger the vulnerable path. Keep upload_max_filesize below post_max_size. If your app never takes multipart uploads, block those requests at the proxy, and remove deprecated or invalid per-request settings from .htaccess files and PHP_VALUE lines.
Leave session.upload_progress.enabled=0 in place even after you patch, unless your site shows upload progress that depends on it. The PHP team suggests exactly that: few sites use the feature, and attackers are now probing it.
A WAF buys time on top. Cloudflare's managed rules cover the Free plan, and AWS and Microsoft have published WAF guidance for their clouds. Requests that reach your origin IP directly skip the WAF, so the patch still has to happen.
What to check after patching
Attacks began before the patch, so a server that ran an exposed build may already have had visitors. Check it anyway.
hunt.sh
# Memory blowups, timeouts and fatal errors in PHP and web server logs
grep -hE 'Allowed memory size|Maximum execution time|PHP Fatal error' /var/log/apache2/error.log /var/log/php*-fpm.log 2>/dev/null | tail -n 50
# PHP code planted inside session files
grep -rl '<?php' "$(php -r 'echo ini_get("session.save_path") ?: "/var/lib/php/sessions";')" 2>/dev/null
# PHP files added or changed in the web root since 1 October
find /var/www -name '*.php' -newermt '2026-10-01' -ls
# What the web user is running right now
ps -u www-data -o pid,etime,cmdBursts of out-of-memory errors from one IP, multipart POSTs to pages that take no uploads, and session files holding PHP code all deserve a closer look. JUMPSEC's read-only phpocalypse script gathers logs, settings and session files into one ZIP for review. A clean result is not proof, since some attack paths leave traces only in memory.
Treat a hit as a breach: isolate the host, keep the logs and rebuild from a clean image. If personal data may have left the server, breach-notification deadlines can apply, so bring in whoever handles legal and privacy for you early. Rotate database passwords and API keys whether or not data left.
Is PHP2Shell being exploited?
Yes. Cloudflare has seen attack traffic against its customers, with payloads reworked to slip past its rules. Amazon's threat intelligence team published a report titled "Amazon Threat Intelligence identifies PHP2Shell exploitation prior to public disclosure in MadPot". The official record is still open. CISA's Known Exploited Vulnerabilities catalog (version 2026.10.21) listed neither CVE when we checked. We will add the entry here when it appears, and the Mindber news desk carries the follow-ups.
The disclosure itself moved faster than planned:
PHP2Shell: from patch to public exploits
- 1
19 October: release tags signed
Tags for the fixed PHP releases are signed in the php-src repository. php.net later said Linux distributions and LTS vendors received the patches in advance. - 2
20 October, 20:32 UTC: advance warning
php.net announces a critical release for 21 October at 14:00 UTC, two flaws rated 9.2, and keeps the right to ship early if details leak. - 3
21 October, 03:02 UTC: WAF rules live
Cloudflare's managed rules start protecting Free and paid plans by default, about nine hours before public disclosure. Cloudflare says details had leaked before the planned date. - 4
21 October: fixes and advisories ship
The four fixed PHP releases come out with both advisories. FrankenPHP ships a rebuilt release the same day. - 5
By 22 October: governments and vendors respond
CISA, the UK NCSC, the Canadian Centre for Cyber Security, the Australian Signals Directorate and CERT-EU publish alerts. Cisco, F5, Palo Alto Networks, Fortinet and Sophos post advisories for their own products. - 6
21 to 22 October: exploit code is public
Repositories offering proof-of-concept and exploit code appear on GitHub on 21 October, within hours of the release. Mindber did not test them. By 22 October a search for php2shell returns 534 repositories, most of them scanners, detection rules and mitigation scripts.
What this incident says about patching
Most PHP shops patch on a schedule: a monthly window, a staging run, a quiet deploy. PHP2Shell broke that rhythm. The details leaked before the planned release, exploit repositories appeared within hours, and the PHP team scored both bugs 9.2 on CVSS v4.0, inside the critical band. A server patched in next week's window would have spent days exposed to attacks already circulating.
That argues for a second, faster path you set up before you need it. It has three parts. Run a quick compatibility check on a staging copy, roll out to your most exposed servers first (mod_php), and then confirm that the running workers use the new build. An updated package on disk proves nothing about them. The last part is the one most often skipped, and Step 3 above exists because of it.
Part of the speed comes from how the bugs were found. Researchers from Calif.io, Wiz, OpenAI and Quarkslab reported them, according to Cloudflare. Cloudflare also says every release from PHP 5.4 onward carries the flaws, so the faulty code has shipped since 2012. Wiz headlined its write-up "AI uncovers critical RCE vulnerabilities affecting 70% of the Internet", and OpenAI says its models helped the researchers.

OpenAI's announcement says the company led a coalition of maintainers and researchers for two months before disclosure. Source: OpenAI on X.
Code that people had read for more than a decade fell to AI agents. They can follow one edge case, such as memory running out on one exact line, and test it over and over. Attackers have the same tools. We expect more bugs of this kind in old, widely deployed code, found and weaponized on the same short clock. That is the case for having the fast patch path ready before the next disclosure, not inventing it during one.
More from Mindber
- October 2026 security roundup: the Node.js, NGINX, Go, GitLab and eMudhra fixes from the same week, with what to patch first.
- ASEAN AI compliance guide: breach-notification deadlines in Malaysia, Singapore and the Philippines.
- Loop engineering: how AI agents test an idea over and over, the same pattern that found these bugs.
- Claude Fable 5 suspended: why Anthropic held its cyber-capable Mythos 5 model back for vetted defenders.
- NVIDIA NemoClaw: infrastructure-level security controls for AI agents on your own machines.
- Claude Code and ChatGPT, with Codex, can read
php.ini, FPM pools and.htaccessfiles and flag the per-request settings the advisory warns about. Give them read-only access on production. - AI coding agents: the directory category for those tools.
- AI agent procurement guide: breach-notification questions worth asking a host that processes customer data.
- Rankings, discover, our methodology and the liveness checks that track whether a tool is still maintained.
Frequently asked questions
Is my WordPress site affected by PHP2Shell?
Yes, if the server runs an unpatched PHP build, whatever your WordPress version. To see which PHP serves the site, open Tools, then Site Health, then the Info tab, and expand Server. If that version is older than the fixed release for its branch, ask your host whether a backported package is installed.
Do I need to change my PHP code?
No code change fixes PHP2Shell, since both bugs sit in the engine. The advisory still asks you to remove fatal errors and timeouts an attacker can trigger, for example in upload, import or cleanup code. On a server that is not yet patched, each one can start the CVE-2026-109619 chain.
Does PHP2Shell affect command-line PHP and cron jobs?
php.net scopes the risk to PHP installations that serve web requests, so a script run only by cron is not the target. Upgrading every PHP package, as Step 2 does, patches the command-line binary as well, and only the web-facing workers need the restart.
How can I see whether Cloudflare blocked PHP2Shell attacks on my site?
In the Cloudflare dashboard, open Security, then Security Analytics, then Events, and filter by the managed rule IDs Cloudflare published for PHP2Shell. Free plans get the rules automatically through the Cloudflare Managed Free Ruleset. On Pro, Business and Enterprise, confirm that the Cloudflare Managed Ruleset runs in block mode.
Is PHP 8.6 affected by PHP2Shell?
Its test builds were. PHP 8.6.0 RC4 includes the fixes, so anyone running an earlier 8.6 alpha, beta or release candidate should update, and php.net still says not to use it in production. The final release candidate, RC5, is planned for 5 November 2026.
Sources & methodology
Editorial analysis of the PHP project's own advisories and announcements plus named security vendors and national CERTs, retrieved 2026-10-22. This is a developing story. Every version number and setting comes from a linked primary source. Follow each link for the current position.
- [1]CVE-2026-109618: RCE via OOM corruption, CVSS v4.0 9.2, fixed in 8.2.35, 8.3.36, 8.4.27 and 8.5.12, mitigations and SAPI analysisPHP security advisory GHSA-w8hw-w9fx-j79w · 2026-10-21
- [2]CVE-2026-109619: RCE via stale global state, confirmed producers and consumers, session upload progress and fatal_error_backtraces mitigationsPHP security advisory GHSA-6wmf-4rv5-p3rp · 2026-10-21
- [3]Who is at risk, fixed releases, source backports for 7.4, 8.0 and 8.1, temporary mitigationsphp.net: Security advisory, update now · 2026-10-21
- [4]Advance notice of the release scheduled for 21 October at 14:00 UTCphp.net: Upcoming Critical PHP Security Release · 2026-10-20
- [5]Disclosers, pre-disclosure leak, WAF rules live at 03:02 UTC, PHP 5.4+ affected, about 70% of websites, attack traffic observedCloudflare blog · 2026-10-21
- [6]FrankenPHP 1.13.2 security release and its four FrankenPHP-specific fixesFrankenPHP release notes · 2026-10-21
- [7]Affected-products list (QNAP, Palo Alto, Citrix NetScaler, Check Point vulnerable; pfSense, OPNsense fixed), cPanel mitigation scriptNCSC-NL php2shell repository · 2026-10-22
- [8]PHP2Shell exploitation in MadPot honeypots before disclosure (report title only, page not read)Amazon Security Blog · 2026-10-22
- [9]Government alerts (CISA, UK NCSC, CCCS, ASD, CERT-EU) and vendor advisories (Cisco, F5, Palo Alto Networks, Fortinet, Sophos)Queensland Government CTI: PHP2Shell resources · 2026-10-22
- [10]Header-based version checker and its limitsOpenAI php2shell-checker · 2026-10-22
- [11]Read-only triage script for session-file and log indicatorsJUMPSEC phpocalypse · 2026-10-22
- [12]Node.js 10 CVEs, severities and fixed versions 26.12.1, 24.22.1, 22.23.4Node.js: October 2026 security releases · 2026-10-21
- [13]NGINX 1.31.7 and 1.30.6 fix five CVEs; 1.31.8 lists no security fixesnginx/nginx GitHub releases · 2026-10-21
- [14]Go crypto/x509 blocks a small set of intermediates, CVE-2026-111943, Go 1.27.3 and 1.26.10Go issue #82345 · 2026-10-20
- [15]GitLab 19.5.1 with 14 security changes, plus 19.4.3 and 19.3.6GitLab CHANGELOG at v19.5.1-ee · 2026-10-20
- [16]Eight eMudhra intermediates under emSign ECC Root CA - G3 compromised and revoked; certifi 2026.10.19 and uv 0.13.4
- [17]SimpleXML garbage-collection regression in 8.4.27 and 8.5.12, closed as fixedphp-src issue #24488 · 2026-10-22
Keep reading
Claude Fable 5 Suspended by US Government Order
How cyber-capable AI models ended up under export controls, and what that means for defenders.
NemoClaw: NVIDIA's open-source AI agent security stack
Infrastructure-level security controls for AI agents that run on your own machines.
ASEAN AI Compliance Guide 2026
Breach notification and data rules SaaS teams in the region need to know.
This article is an analysis of public information. It is not original security research, and Mindber did not test any exploit or server. All facts were checked against the sources above on 22 October 2026. The situation is still developing, so follow the PHP project and your vendors for the latest fixed versions. Spot an error? Tell us. Corrections ship within 24 hours.
Learn the basics on Mindber
New to AI? These free Mindber pages explain the ideas behind articles like this one.
Share this article
Legal notice
This publication constitutes editorial commentary on publicly available information and does not constitute financial, legal, investment, or professional advice. Product names, trademarks, and registered trademarks referenced herein are the property of their respective owners; their appearance does not imply endorsement or affiliation. Mindber's analysis reflects editorial judgment based on public signals and is subject to change without notice. Scores are not buy, sell, or hold recommendations. No commercial relationship exists between Mindber and the vendors evaluated unless separately disclosed in writing. This publication is governed by the laws of Malaysia. Any dispute arising from or in connection with this publication shall be submitted to the exclusive jurisdiction of the courts of Malaysia.