On October 20, 2026, two CVE identifiers leaked on social media. They belonged to two critical remote code execution bugs in PHP itself — not in WordPress, not in Laravel, not in any plugin. The PHP project moved its emergency release forward by one day. Patches landed October 21, 2026 at 14:00 UTC.
The short version: update PHP to 8.5.12, 8.4.27, 8.3.36, or 8.2.35, then restart every PHP worker. If you run an end-of-life branch, upgrade or take the backport from your distribution. Configuration tweaks reduce risk. They do not fix the bug.
Affected: every PHP version from 5.4 onward — around 69% of websites whose server-side language is known.
# Check what version your server actually serves (not just the CLI)
php -v
curl -sI https://your-site.example | grep -i '^server'
# Then confirm the package changelog, not just the version number
zgrep CVE-2026-109618 /usr/share/doc/php8.3-common/changelog.Debian.gz
If that command finds nothing and your PHP is below the fixed versions, you are exposed. Keep reading.
What Actually Happened
This was not a quiet patch Tuesday.
- August 1, 2026 — Calif researcher Ryan Austin discovers the first flaw while auditing PHP's source with help from OpenAI's GPT-5.6 Sol model. Root cause traces back to an out-of-memory issue first spotted during PHP's 2024 external security audit.
- August 11 — Calif reports an unconditional RCE to the PHP security team; OpenAI independently reports the same root cause the same day.
- August 19–24 — Wiz Research, using its own Atlas tooling plus Gemini 4 Argon and GPT-5.6 Sol, independently finds the first vulnerability, confirms RCE against Drupal and WordPress, and reports to PHP's security team on August 24.
- September 18 — OpenAI reports additional attack vectors.
- October 20, ~15:00 UTC — Both CVE IDs leak on forums and social media, with a wrong CVSS score of 10.0 and a wrong release time. No technical details leak.
- October 20, 19:30 UTC — PHP publishes an advance notice, pulling the release forward from its planned date.
- October 21, 07:41 UTC — Chainguard publishes built images containing the fix, more than six hours before the coordinated release.
- October 21, 07:43 UTC — Cloudflare reports early attack traffic.
- October 21, 14:00 UTC — PHP releases fixed versions. The release had originally been scheduled for October 22.
Worth calling out: all three organizations involved — Calif, Wiz, and OpenAI — used AI models (GPT-5.6 Sol, Gemini 4 Argon) as part of the auditing process that surfaced these bugs. The underlying weakness had been sitting in PHP's source since version 5.4 (2012) and a PHP Foundation developer had flagged something suspicious in that same area back in 2024, but nobody had a concrete attack path. AI-assisted auditing found one. OpenAI used the moment to launch a "Patch the Planet" push, committing $1 billion in subsidized model access for defenders. Expect this pattern — AI tooling surfacing exploitable bugs in codebases that have been "safe enough" for over a decade — to show up more, not less.
The PHP Foundation was blunt about the delay in fixing the underlying issue: competing fixes each broke backward compatibility, added denial-of-service risk, or required coordinated changes across many third-party extensions. The security team works by consensus, and consensus stalled. That is a structural failure, and the Foundation says so in its own post.
Separately, Amazon Threat Intelligence observed a php2shell exploitation attempt against its MadPot honeypot network on October 17 — four days before public disclosure, from an IP tied to a commercial anonymization network. It is unclear how the attacker got exploit information.
The Two Bugs in Plain Language
PHP does not start a fresh process for every request. It reuses worker processes to stay fast. Both bugs corrupt the memory of a reused worker.
CVE-2026-109618 — Out-of-memory corruption
What it does: A request hits PHP's memory_limit at exactly the wrong moment. PHP bails out mid-operation and leaves internal request data half-initialized. Later cleanup code treats that garbage as valid and corrupts memory.
Analogy: A chef gets interrupted halfway through prep and leaves the knife on the counter. The next cook grabs it without looking.
Worst case: Apache with mod_php. The trigger fires before your application code runs, so no login, no plugin, no framework router, no WAF rule inside the app can stop it. Full RCE was demonstrated with default settings.
CVE-2026-109619 — Stale global state
What it does: A fatal error leaves global state pointing at memory that belonged to a previous request. The worker does not reset it properly. A later request handled by the same worker reads that freed memory — a use-after-free.
Analogy: A hotel reuses a room key. Guest A checks out, the lock is not rekeyed, and guest B's key opens a room still holding guest A's luggage.
Confirmed: use-after-free, worker crash, and RCE against a real-world application on Apache mod_php. Also confirmed on PHP-FPM through application-level code paths.
There is a data leak too
Researchers demonstrated unauthenticated disclosure of PHP worker memory. CVE-2026-109618's upload-progress handler can return freed worker memory to the client inside a PHPSESSID response cookie. That memory can contain passwords, session tokens, API keys, and TLS private keys from other requests. The handler runs before application code, so it works even when the app never calls session_start().
If you ran unpatched PHP on a shared worker pool, assume credentials that passed through it may have leaked.
Severity
| CVE | Title | CVSS v4.0 | Class |
|---|---|---|---|
| CVE-2026-109618 | RCE via OOM corruption | 9.2 | Use of uninitialized memory, use-after-free |
| CVE-2026-109619 | RCE via stale global state | 9.2 | Heap use-after-free, memory disclosure |
Both are AV:N/AC:H/AT:P/PR:N/UI:N — network reachable, no privileges, no user interaction. Attack complexity is High because exploitation depends on allocator layout, build flags, and worker scheduling. That is the one piece of good news.
Affected Deployments
PHP considers every installation that serves web requests at risk:
- Apache
mod_php— highest priority. Demonstrated exploit runs before application code. - PHP-FPM — affected. FPM startup blocks one specific OOM path, but PHP validated session-lifecycle RCE against FPM under suitable application conditions.
- php-cgi, FrankenPHP, LiteSpeed — affected.
- Shared hosting — you probably cannot patch this yourself. Your provider must.
The vulnerable code dates to PHP 5.4.0, released in 2012.
Every PHP Framework and CMS Is Affected
This is the part people get wrong. The bug is in the interpreter, below your framework. No WordPress update, Laravel update, or plugin update fixes it. Patching the app while leaving PHP old changes nothing.
Calif confirmed pre-authentication RCE — no login required — against these specific versions:
| Application | Version tested by Calif |
|---|---|
| WordPress | 7.1.2 |
| Drupal | 11.4.3 |
| Joomla | 6.1.4 |
| MediaWiki | 1.46.2 |
| Magento 2 / Adobe Commerce | 2.4.9 |
| Laravel | 13.11 |
| Symfony | 8.1 |
| Nextcloud | 35.0.1 |
| Roundcube | 1.7.4 |
| phpMyAdmin | 5.2.3 |
| WHMCS | — |
Same engine-level exposure applies to everything else running on PHP 5.4+: CodeIgniter, CakePHP, Yii, Zend/Laminas, Slim, PrestaShop, Shopware, WooCommerce, OpenCart, Sylius, phpBB, Moodle, Matomo, ownCloud, SuiteCRM, Cacti, e107, and the long tail of custom PHP applications.
Two consequences worth stating plainly:
- WooCommerce stores are Magento/Shopware-class targets. Store code being clean means nothing here. Sansec's guidance to merchants was direct: update PHP, and if you do not manage the server, ask your host which build they run.
- Multi-tenant control panels need attention. cPanel/CloudLinux, Plesk, and DirectAdmin users should check panel changelogs for the CVE. cPanel on CloudLinux shipped fixes for
ea-php52throughea-php85.
Reality check on exploitation
Sansec's follow-up coverage walked back some of the worst-case framing, and it is worth quoting the substance rather than the panic:
- Public PoCs do not work against a default PHP installation.
- Most published exploits need the target application to already have a local file inclusion bug — a severe flaw on its own.
- Nobody has shown a single request that works against any vulnerable server the way Log4Shell did.
- Several Dutch sites went offline as a precaution. You do not need to take your site offline.
This is not a reason to wait. Amazon observed exploitation attempts before disclosure, and attack traffic continues. It is a reason to patch in the correct order instead of panicking.
Fix It: Update PHP
| PHP branch | Fixed version |
|---|---|
| PHP 8.5 | 8.5.12 |
| PHP 8.4 | 8.4.27 |
| PHP 8.3 | 8.3.36 |
| PHP 8.2 | 8.2.35 |
Distribution packages may keep an older version number and still contain the backported fix. Check the advisory and the package changelog, not just php -v.
End-of-life branches
PHP 8.1 and earlier are outside upstream support. The PHP security team published minimal source backports for 7.4, 8.0, and 8.1. Get a fixed build from your vendor:
| Environment | Source | Fixed versions |
|---|---|---|
| Debian, Ubuntu | deb.sury.org / ppa:ondrej/php |
5.6, 7.4, 8.0, 8.1 |
| Ubuntu 22.04 | Ubuntu security | 8.1 |
| Ubuntu 14.04–20.04 | Ubuntu Pro (+ Legacy add-on) | 7.4 / 7.2 / 7.0 / 5.5 by release |
| Debian 9–11 | Freexian ELTS (paid) | 7.4 / 7.3 / 7.0 |
| RHEL, AlmaLinux, Rocky, Fedora | Remi's repository | 7.4, 8.0, 8.1 |
| AlmaLinux 8–10 | AlmaLinux | every PHP stream shipped |
| RHEL 8, 9 | Red Hat | some streams, others in progress |
| cPanel on CloudLinux | CloudLinux | ea-php52 to ea-php85 |
| Any | TuxCare ELS / ZendPHP LTS (paid) | 5.x to 8.1 |
The official Docker php image gets no fix for 8.1 or older. Build from the php-src security branches, or upgrade.
Restart every worker
Installing the package is step one. Code already loaded in a running worker stays vulnerable until that worker restarts.
# Debian/Ubuntu with FPM — adjust version
sudo apt update && sudo apt install --only-upgrade php8.3-fpm php8.3-cli
sudo systemctl restart php8.3-fpm
# Apache with mod_php
sudo systemctl restart apache2
# Containers: rebuild the image, redeploy, do not just restart
docker compose build --pull app && docker compose up -d app
Then verify the fix is really in place:
php -v
php -r 'echo PHP_VERSION, PHP_EOL;'
# Debian/Ubuntu
zgrep CVE-2026-109618 /usr/share/doc/php8.3-common/changelog.Debian.gz
# RHEL family (Remi parallel packages: php83-php-common)
rpm -q --changelog php-common | grep CVE-2026-109618
For a web request, check the PHP version served by the web server, not the CLI. Parallel installs are common: php -v may report a patched binary while Apache loads a different, older module.
Temporary Mitigations While You Schedule the Patch
These are partial. PHP says updating is the only complete fix.
1. Block multipart/form-data at the web server
Every known trigger is a multipart/form-data request. PHP parses that body before your application runs. Reject it at the edge.
nginx — add inside every server block that passes requests to PHP:
if ($http_content_type ~* "multipart/form-data") {
return 403;
}
sudo nginx -t && sudo systemctl reload nginx
Apache — add inside every <VirtualHost> that serves PHP:
RewriteEngine On
RewriteCond %{HTTP:Content-Type} multipart/form-data [NC]
RewriteRule ^ - [F]
This breaks file uploads, including product images in admin panels. Some carts and checkout forms submit as multipart, so place a test order after adding the rule. Remove the rule once PHP is patched.
2. PHP settings
Calif published two partial mitigations. PHP core developer Gina Peter Banyard warned that disabling session upload progress alone is not enough — combine these with the multipart block.
For Apache mod_php, in php.ini or a drop-in under conf.d:
session.upload_progress.enabled = 0
memory_limit = -1
fatal_error_backtraces = 0
For PHP-FPM, set them in every pool file — FPM reads pool config, not the CLI php.ini:
; /etc/php/8.3/fpm/pool.d/www.conf
php_admin_flag[session.upload_progress.enabled] = off
php_admin_value[memory_limit] = -1
php_admin_value[fatal_error_backtraces] = 0
sudo systemctl reload php8.3-fpm
Then confirm the values from a PHP-FPM-served request. A CLI check proves nothing.
Warnings on memory_limit = -1: you are removing PHP's per-request memory cap. One request can now consume all server memory. Watch memory use, keep a container or cgroup limit as an availability boundary, and restore a finite limit after patching. Do not use RLIMIT_AS or RLIMIT_DATA — they can force allocation failures that trigger the vulnerable path.
3. Reduce request surface
- Lower
post_max_sizeto 8M without uploads, or 32M with uploads. Keepupload_max_filesizebelow it. - Lower
max_input_nesting_levelfrom its default 64. - Bound
max_file_uploads, multipart parts, and header counts at the proxy. - For FPM,
pm.max_requests = 1limits each worker to one request. Only if the performance cost is acceptable. - Remove invalid or deprecated per-request INI settings (
php_valuein Apache config or.htaccess). They generate diagnostics before initialization.
4. Edge protection is a stopgap only
Cloudflare deployed WAF rules for the known exploit vectors, available to all plans including free. That only covers traffic routed through Cloudflare. It is a stopgap, not a fix.
If You Cannot Patch Today
- Assign an owner and a deadline to every host still on old PHP. Unassigned means unpatched.
- Take truly unpatchable internet-facing PHP systems offline. CISA recommended exactly that for unsupported branches.
- Restrict public access to admin panels,
/phpmyadmin, and staging hosts. - Rotate secrets that passed through any unpatched shared worker: session keys, API tokens, database passwords, TLS private keys.
- Start incident review from October 17, not October 21. Amazon observed attempts on that date.
Detection and Verification Checklist
- Find every PHP install — parallel branches, containers, hosting panel packages, appliance-bundled copies, and that forgotten staging VM.
- Update the right package, binary, or image — check the vendor changelog for the CVE, not only the version string.
- Restart or replace every worker — then verify the running process uses the new build.
- Re-check the mitigation settings — remove the multipart block and restore a finite
memory_limitafter patching. - Test under memory pressure — the patched runtime can terminate a worker immediately at its hard memory threshold, bypassing normal shutdown handlers.
- Re-scan with your vulnerability scanner and validate external exposure.
Why This One Matters Beyond the Patch
PHP runs a large share of the public web: government services, banks, shops, media sites. The security work on the interpreter itself is still done by a small group of foundation-funded developers and volunteers.
The root cause was found in 2024. The fix stalled for two years over compatibility trade-offs. When the full impact became clear in August 2026, the Foundation's team worked through weekends to ship fixes across every supported branch. The Foundation's own conclusion is worth repeating: tools now find bugs faster than anyone can fix them, and deciding the right fix still takes engineers who know the whole codebase. There are too few of them.
If your business runs on PHP, sponsoring the PHP Foundation is the most direct way to reduce the chance that the next one of these stalls for two years.
Timeline
| Date (UTC) | Event |
|---|---|
| 2026-08-01 | Calif finds the first bug, with help from GPT-5.6 Sol |
| 2026-08-11 | Calif reports the first bug, coordinated disclosure starts |
| 2026-08-19 | Wiz independently finds the first vulnerability using Atlas, Gemini 4 Argon, and GPT-5.6 Sol |
| 2026-08-24 | Wiz Research reports to the PHP security team |
| 2026-09-18 | OpenAI reports further vectors |
| 2026-10-17 | Amazon MadPot honeypot records an exploitation attempt |
| 2026-10-20 15:00 | CVE IDs leak with wrong CVSS (10.0) and wrong release time |
| 2026-10-20 19:30 | PHP publishes advance notice |
| 2026-10-21 07:41 | Chainguard breaks embargo with prebuilt images |
| 2026-10-21 07:43 | Cloudflare reports early attacks |
| 2026-10-21 14:00 | PHP releases 8.5.12, 8.4.27, 8.3.36, 8.2.35 |
References
- PHP security advisory — critical RCE vulnerabilities
- GHSA-w8hw-w9fx-j79w — CVE-2026-109618
- GHSA-6wmf-4rv5-p3rp — CVE-2026-109619
- The PHP Foundation — today's release and how PHP security is changing
- Calif — php2shell technical writeup
- Sansec — PHP2Shell research and e-commerce guidance
- Qualys — find, mitigate, and patch PHP2Shell
- Unit 42 — threat brief
- Tenable — PHP2Shell FAQ
- CISA alert — patch immediately
- CERT-EU advisory 2026-018
- Amazon Threat Intelligence — exploitation before disclosure
- Wiz Research — PHP2Shell disclosure