The story: a leak, a countdown, and a four-day head start for attackers
On October 20, 2026, two CVE identifiers started circulating on Hacker News and social media before any fix existed. The PHP security team had a release scheduled for October 22 — and moved it up a day, publishing the emergency update on October 21 at 14:00 UTC. The reason, per the PHP Foundation: the identifiers had leaked, and an exploit demonstration video was already public.
Then the timeline got worse. Amazon Threat Intelligence reported an exploitation attempt against its MadPot honeypot network on October 17 — four days before public disclosure — followed by more attempts on October 21 with payloads and infrastructure suggesting multiple actors. Cloudflare's CTO said the company was "seeing early attacks emerging" and shipped WAF rules to all customers, including the free tier, as a stopgap. watchTowr reported it reproduced both flaws and observed exploitation attempts against both.
The research credited by the PHP Foundation — Calif, OpenAI, and Wiz — has an uncomfortable detail for the industry: Calif and Wiz both said they used AI models in their research. The same class of tooling that found the bug can be pointed at unpatched servers. We covered a very different face of this problem in Google's Gemini incident: when AI agents breached three real companies — worth reading alongside this one, because both stories end with the same lesson: the patch window is now an AI-speed problem.
Quick Answer
Am I affected? If any server serves web requests with PHP — WordPress, Drupal, Joomla, Magento, Laravel, or custom apps — yes. What do I do? (1) Check the version: php -v (or your host's panel, or WordPress Site Health). (2) If you run 8.2–8.5, update to 8.2.35 / 8.3.36 / 8.4.27 / 8.5.12 through your distribution or hosting panel — Linux vendors received the patches in advance. (3) Restart every PHP worker after the update. (4) If you run 7.4–8.1, either apply the PHP team's minimal source backports or upgrade to a supported branch. (5) If you run 7.3 or older, there is no fix — upgrade, or follow CISA's advice and take the system offline. (6) Audit logs and file trees for webshells starting from October 17, not from the disclosure date.
Key Takeaways
- Two unauthenticated RCE flaws in the PHP engine itself — they fire during request parsing, before application code runs, so app-level frameworks and plugins cannot save you.
- Both rated CVSS v4.0 9.2 by the PHP security team (the 10.0 score that circulated before release was incorrect, per the PHP Foundation).
- CVE-2026-109619 also has confirmed memory disclosure impact — worker memory can leak passwords, tokens, and API keys.
- mod_php is the highest-risk setup per the PHP team; a demonstrated exploit triggers on an unauthenticated request there.
- Fixed versions: 8.5.12, 8.4.27, 8.3.36, 8.2.35. Branches 7.4–8.1 get minimal source backports only; 7.3 and older get nothing.
- PHP's own position: updating is the only complete fix. Configuration changes only reduce exposure to specific attack paths.
The two flaws, in plain words
You do not need to be a C developer to understand what broke. Both flaws live in the same place: the gap between "a request died mid-processing" and "the worker cleans up and moves on."
| CVE | Nickname | What breaks | CVSS v4.0 |
|---|---|---|---|
| CVE-2026-109618 | OOM corruption | When PHP aborts a request that exceeded memory_limit, half-initialized request data is treated as valid during cleanup | 9.2 |
| CVE-2026-109619 | Stale global state | Leftover state from one request keeps pointing at freed memory; the next request on the same worker uses it (use-after-free) | 9.2 + memory disclosure |
The first flaw works like this: PHP enforces your memory_limit by aborting the offending request — think of it as an emergency brake. The bug is that when that brake fires at the wrong moment, the request's data is only half-built, and the cleanup crew that follows treats that half-built data as finished, valid instructions. An attacker can deliberately run the engine out of memory using nothing more exotic than a crafted form upload that stays within normal-looking limits — a request without a usable content length, or multipart parts carrying enormous numbers of headers.
The second flaw is a classic use-after-free wearing modern clothes. A PHP worker handles many requests in a row. After a fatal error, some global state — session data, error handlers, object and extension state — still points at memory that has already been freed. The next request served by that same worker can walk into that stale state before normal initialization resets it. Researchers demonstrated not just code execution this way, but also reading the worker's memory — which is where credentials and tokens live.
Who is affected — the honest matrix
PHP's advisory is blunt: every installation that serves web requests is at risk. But the risk is not equal everywhere.
| Your setup | Exposure | Why |
|---|---|---|
| Apache with mod_php | [FAIL] Highest risk | PHP's demonstrated exploit triggers on an unauthenticated request before any application code runs; PHP explicitly flags mod_php as highest risk |
| PHP-FPM (nginx, Apache proxy) | [FAIL] Affected | Same engine flaws; worker reuse makes the stale-state path reachable |
| php-cgi | [FAIL] Affected | Named in the advisory |
| FrankenPHP / LiteSpeed | [FAIL] Affected | Named in the advisory |
| PHP used only for CLI scripts (no web serving) | [WARN] Low practical risk | The flaws are in request parsing; cron scripts that never serve HTTP are a much harder target |
| Static sites, no PHP anywhere | [OK] Not affected | Nothing to patch — verify with your host if unsure |
Scale, for those who want it: W3Techs tracks PHP at 69.3% of websites whose server-side language is known. Researcher estimates of internet-exposed PHP hosts ranged from roughly 1.3 million to 1.9 million in the days after disclosure. Calif, the research group credited by the PHP Foundation, said it confirmed pre-authentication RCE against specific versions of WordPress, Drupal, Joomla, and Magento.
The version trap most guides skip
This is where a lot of coverage gets vague, so here is the full picture with nothing smoothed over:
| Your PHP branch | Status | Your options |
|---|---|---|
| 8.5.x before 8.5.12 | [FAIL] Vulnerable, fix available | Update to 8.5.12 |
| 8.4.x before 8.4.27 | [FAIL] Vulnerable, fix available | Update to 8.4.27 |
| 8.3.x before 8.3.36 | [FAIL] Vulnerable, fix available | Update to 8.3.36 |
| 8.2.x before 8.2.35 | [FAIL] Vulnerable, fix available | Update to 8.2.35 |
| 7.4 through 8.1 | [FAIL] End-of-life, no official release | Minimal source backports from the PHP security team (you build from source), or upgrade to a supported branch, or ask your distribution/LTS vendor |
| 5.4 through 7.3 | [FAIL] End-of-life, no fix exists | Upgrade to a supported release — or take the system offline (CISA's recommendation for anything that cannot be updated) |
Read that table twice if you manage older applications. The uncomfortable truth: if you are on PHP 8.1 or older, there is no package update coming for your exact branch. The PHP security team published minimal source backports for 7.4 through 8.1 for organizations that build PHP from source — that is a stopgap for fleets with hard compatibility constraints, not a home for your application long-term. The end-of-support treadmill is the same one Windows administrators know well; we track the Windows side of it in Is Windows 10 still safe? — the security math is identical on any platform.
The fix ladder — run it in order
1. Find out what you are actually running
On the server command line: php -v. For the version the web server really uses, create a temporary page calling phpinfo() — or check your hosting panel. WordPress users: Tools → Site Health → Info → Server shows the PHP version without touching any files. If you are on shared or managed hosting, the panel (or a quick support ticket) is your source of truth.
2. Supported branch (8.2–8.5): update through your normal channel
Linux distributions and LTS vendors received the patches in advance — check your vendor's advisories and update with your package manager as usual. Self-managed Ubuntu/Debian administrators commonly use the community PHP packages; RHEL-family administrators use their distro's PHP or the well-known third-party repository. cPanel/WHM servers update through EasyApache 4 / MultiPHP packages. Docker images: change the base image tag to the fixed version (for example a php:8.4.27 tag family) and rebuild. Windows/IIS binaries come from the official PHP for Windows downloads. macOS developers using Homebrew: brew upgrade php.
3. Restart every PHP worker — not just the web server
This step is easy to miss and it matters: the fixes live in the PHP engine, and long-running worker processes keep the old code in memory until they are restarted. Restart php-fpm (or reload its workers), restart Apache where it embeds PHP, and recycle any application containers. After any configuration change, PHP's advisory explicitly says to restart every PHP worker.
4. Verify the version after the update
Run php -v again on the command line — and re-check the phpinfo page or Site Health for the version the web stack actually serves. On multi-server fleets, version-check every host; the one you forget is the one that gets probed.
5. End-of-life branch (7.4–8.1): backport or upgrade
Backporting source builds is specialist work — if those words do not describe your team, treat "upgrade to 8.2.35 or newer" as the real task. Budget compatibility testing for your application and plugins; do it against a staging copy, not production.
6. Ancient PHP (7.3 and older): there is no patch for you
This is not a scare line — it is arithmetic. No fixed release exists for your branch and none is coming. Upgrade, or isolate the system from the internet until you can. CISA's October 21 alert says exactly this: organizations that cannot update, or that still run unsupported PHP 8.1 or earlier, should take PHP-based systems offline until patched or updated.
7. Managed hosting and WordPress.com-style platforms: confirm, do not assume
Major managed hosts patched server-side within hours and published status pages. Your job is verification: check the host's status page and confirm your site's PHP version in Site Health. If your host has not communicated anything about PHP2Shell by now, that itself is your answer about their incident process — and worth an escalation ticket.
Cannot patch today? The documented mitigations — and their limits
For servers that genuinely cannot update immediately, the PHP advisory lists these configuration changes:
- For CVE-2026-109618: set
memory_limit=-1in a way applications cannot override. This removes the out-of-memory abort path the flaw abuses — at the cost of removing your memory safety net, so a runaway application can now consume all server RAM. PHP suggests a container or cgroup memory limit as the availability boundary if you go this route. - For CVE-2026-109619: set
session.upload_progress.enabled=0, and on PHP 8.5 alsofatal_error_backtraces=0. - Restart every PHP worker after making these changes — stale state already in memory is exactly what the second flaw feeds on.
Beyond PHP's own guidance:
- If you are behind Cloudflare: WAF rules covering the known exploit vectors were deployed to all customers, including the free tier. Cloudflare itself calls this a stopgap — it only covers traffic routed through Cloudflare, and new variants may not match the rules.
- CERT-EU's recommendation for organizations that cannot update right away: consider isolating internet-facing applications from public networks until the fix is applied and verified.
- CISA's recommendation for anything unpatchable or unsupported: take it offline.
How to check whether you were already hit
Amazon's guidance deserves emphasis: start investigations from at least October 17, not from the disclosure date — that is when the first honeypot exploitation attempt landed. Work through this checklist on every PHP host:
1. Web server access logs: look for the trigger shapes
The known pre-auth vectors are requests engineered to exhaust memory during parsing — for example requests without a usable content length, or multipart uploads carrying enormous numbers of headers. In nginx and Apache logs, hunt for oversized or malformed POSTs, bursts of identical requests from single IPs, and any request that returned a 500 or closed the connection during upload. Unusual Content-Length values next to tiny response sizes are worth a second look.
2. Hunt for webshells — the giveaway is in the file tree
The nickname PHP2Shell exists because the end goal of this exploit class is dropping a shell. Triage commands for a start:
find /var/www -name '*.php' -mtime -30 -ls (recently modified PHP files)
grep -rnE 'eval\s*\(|assert\s*\(|system\s*\(|shell_exec\s*\(|passthru\s*\(' /var/www --include='*.php' | less
Expect false positives — frameworks use some of these functions legitimately — which is why you review hits rather than delete blindly. Anything combining base64_decode with eval, or sitting in an uploads directory, jumps the queue.
3. Persistence checks
Attackers who get RCE usually stay: check crontab -l and /etc/cron.* for new entries, review ~/.ssh/authorized_keys for unknown keys, and look for new admin users in your application's database. Changed timestamps on wp-config.php or equivalent configuration files are a red flag.
4. Rotate secrets if you find anything
Database credentials, application salts and keys (WordPress: the AUTH_KEY family in wp-config.php), API tokens, and SMTP credentials — all of it rotates if compromise is confirmed. Remember the second flaw's confirmed impact is reading worker memory: credentials that passed through a compromised worker should be considered exposed even if you find no shell.
5. Check the mail path
Compromised servers get used for spam and phishing, and that burns your domain's reputation. If your server sends mail, verify your SPF, DKIM, and DMARC posture — our email authentication guide walks the full check. If suspicious mail already went out in your name, our Email Header Forensic Analyzer runs client-side in your browser to examine what was actually sent.
Do this, never that
| [OK] Safe and effective | [FAIL] Makes things worse |
|---|---|
| Update to a fixed version and restart every PHP worker | Installing "PHP2Shell patcher" tools from ads — after events like this, scareware appears within hours (the same pattern we documented in fake virus pop-ups) |
| Set the documented mitigation configs if you truly cannot patch yet | Treating memory_limit=-1 as "the fix" and moving on with your week |
| Assume WAF rules are a bridge, not a wall | Dismissing the risk because "nobody targets my small site" — honeypot data shows indiscriminate scanning |
| Audit logs and files back to October 17 | Auditing only from October 21 and calling it clean |
| Test the upgrade on staging first | Force-upgrading a PHP 5.6 legacy app to 8.5 in production on a Friday afternoon |
Why this keeps happening — and what it means for you
This is not PHP's first rodeo with the CISA Known Exploited Vulnerabilities catalog. CVE-2024-4577 (PHP-CGI argument injection) and CVE-2019-11043 (PHP-FPM RCE on nginx) are both in KEV, and both have known ransomware use. PHP2Shell had not been added to KEV as of October 23 — but with in-the-wild exploitation already reported by multiple teams, the pattern is familiar: pre-auth engine flaws get productized fast, and the victims are rarely the interesting targets, just the unpatched ones.
The second lesson is the AI one. The disclosure credits — Calif, OpenAI, Wiz — include two teams that said they used AI models to find this. Attackers read the same advisories. The practical consequence for an administrator is simple: the viable patch window is shrinking, and "we'll get to it this quarter" is no longer a plan. Every serious security program we have covered — from AI agent containment to email authentication — reduces to the same discipline: know what you run, and patch it while the patch is boring.
One sitting, in order — stop when your exposure is gone:
- Inventory:
php -von every host (Step 1). - Update supported branches to 8.2.35 / 8.3.36 / 8.4.27 / 8.5.12 (Step 2).
- Restart every PHP worker (Step 3) and verify versions (Step 4).
- EOL branches: backport or schedule the upgrade (Steps 5–6).
- Documented mitigations only where patching is impossible today.
- Audit from October 17: logs, file tree, persistence, secrets (checklist above).
Frequently asked questions
Is my WordPress site affected?
WordPress itself runs on PHP, so the question is your server's PHP version, not your WordPress version. Calif confirmed pre-authentication RCE against specific versions of WordPress, among other applications. Check Tools → Site Health → Info → Server for the PHP version; 8.2.35, 8.3.36, 8.4.27, or 8.5.12 (or newer) means you are patched. On managed hosting, verify the host actually rolled it out.
Does Cloudflare's WAF fully protect me?
No — and Cloudflare says so itself. The rules cover the known exploit vectors for traffic routed through Cloudflare, and the company explicitly describes them as a stopgap while you patch. New exploit variants may not match existing rules, and any traffic that bypasses Cloudflare is unaffected by them entirely.
Should I test the exploit PoCs circulating online?
No. Tenable notes that unverified exploit code circulating publicly is sometimes laced with malware, and the PHP Foundation said its security team inspected the PoCs that appeared after the leak and did not identify functional exploits at the time of release. Running attacker-side tooling on your own production hosts to "check" is how incidents become worse incidents. Verify by version number, not by firing shells at yourself.
Is PHP used only for command-line scripts affected?
These particular flaws live in request parsing — the code path that handles incoming web requests. CLI-only workloads that never serve HTTP are a much harder target for them. That said, if the same binary also serves any web traffic anywhere on the host, it is affected and should be patched anyway.
I run PHP 8.1. Can I just apply the backport and stay?
The PHP security team published minimal source backports for 7.4 through 8.1 for organizations that build from source. It closes these specific flaws; it does not turn an end-of-life branch into a supported one — future PHP security fixes will not arrive for 8.1 either. Use the backport to buy scheduled upgrade time, not to cancel the upgrade.
Was this added to the CISA Known Exploited Vulnerabilities catalog?
Not as of October 23. CISA's October 21 alert urges immediate patching and notes it had not observed exploitation at the time of publication — while Amazon, watchTowr, and Cloudflare all reported active attempts. For decision-making, treat the in-the-wild reports as the operative reality; KEV listing is a formality that tends to follow, not lead.
My host says "we're patched." How do I verify?
Independently: WordPress Site Health or a phpinfo page shows the PHP version your requests actually execute on. If it reads 8.2.35 / 8.3.36 / 8.4.27 / 8.5.12 or newer, you are covered. If it reads anything older, the host's status page and your site are telling different stories — escalate with the version number in hand.
The bottom line
PHP2Shell is the rare vulnerability where the official guidance contains no nuance to debate: update to a fixed version, restart your workers, and — if you cannot — shrink your exposure deliberately instead of hoping. The flaws fire before your application code runs, the exploit had a four-day head start on the patch, and the memory-disclosure impact means credentials that crossed a compromised worker should rotate even when nothing else seems wrong. The version table above is the whole decision tree; everything else in this guide is execution. More security walkthroughs and hardening checklists live in All Guides, and our client-side security tools — including the Email Header Forensic Analyzer — are collected in the Pro Tools Hub.
Sources
- PHP Security Team, security advisory and fixed versions, October 21, 2026. php.net
- PHP Foundation, "Today's PHP security release and how we're strengthening PHP security," October 21, 2026. thephp.foundation
- CISA, "Critical Vulnerabilities in PHP Require Immediate Patching," alert, October 21, 2026. cisa.gov
- CERT-EU, security advisory 2026-018: Critical Vulnerabilities in PHP. cert.europa.eu
- ENISA, joint statement on critical PHP vulnerabilities. enisa.europa.eu
- Palo Alto Networks Unit 42, "Threat Brief: Critical Vulnerabilities in PHP: CVE-2026-109618, CVE-2026-109619." unit42.paloaltonetworks.com
- Tenable, "php2shell: Frequently asked questions about critical PHP remote code execution vulnerabilities," updated October 23, 2026. tenable.com
- Qualys Threat Research, "PHP2Shell: Find, Mitigate, and Patch Now." blog.qualys.com
- watchTowr, "PHP2Shell FAQ: fixes and exploitation status." watchtowr.com
- Amazon Threat Intelligence, "php2shell exploitation prior to public disclosure in MadPot." aws.amazon.com
W3Techs PHP usage data linked in-text. Vulnerability records: CVE-2026-109618 and CVE-2026-109619 (GitHub Advisory Database: GHSA-w8hw-w9fx-j79w and GHSA-6wmf-4rv5-p3rp). All statistics in this article are attributed to their original sources; estimates are labeled as estimates.
Article notes
Get US tech fixes weekly
No spam. Unsubscribe anytime. Tested on Windows 11 24H2.

Comments
Comments
Post a Comment