php2shell: The PHP Bug That Does Not Need Anyone to Click
php2shell (CVE-2026-109618 and CVE-2026-109619) lets attackers run code on PHP servers with no user click. Patch versions, mitigations and what to tell...
Two critical PHP vulnerabilities, known collectively as php2shell, let an unauthenticated attacker run code on a web server by sending it a request. No link, no attachment, no password prompt: nobody at your company has to do anything. PHP shipped fixes on October 21 after the embargo leaked a day early, and watchTowr's honeypots were logging exploit attempts the same day. If you or your clients run anything on PHP, WordPress included, today is patch day.
What happened
It started on the morning of October 20 with a Hacker News post claiming two critical PHP remote code execution bugs were headed for disclosure on Thursday, October 22. The post was taken down, screenshots had already spread, and researchers at watchTowr confirmed within hours that the bugs were real and under embargo.
The PHP security team responded the same day with an advance notice: two critical vulnerabilities, both scored 9.2 on CVSS v4.0, release moved up to Wednesday, October 21 at 14:00 UTC. On October 21 the fixes shipped as PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35, with a security announcement and two GitHub advisories carrying the technical detail. Distributions and LTS vendors had the patches in advance, so package repositories should have builds today.
- The leak
A Hacker News post claims two critical PHP RCEs are headed for disclosure on Thursday, October 22. It is removed, but screenshots circulate.
- Confirmed real
watchTowr confirms the vulnerabilities exist and are under embargo.
- PHP pre-announces
Advance notice: two critical bugs, both CVSS v4.0 9.2. Release moved up to October 21 at 14:00 UTC.
- Fixes ship
PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35, plus two GHSA advisories with full technical detail. Distributions had the patches in advance.
- Exploit attempts
watchTowr's honeypot network records in-the-wild attempts. Huntress sees none across its partner base as of 10 a.m. ET.
Your patch window is the gap between the last two entries. It is measured in hours.
Sources: PHP security team, watchTowr, Huntress.
watchTowr reported exploitation attempts against its Attacker Eye honeypot network on October 21. Huntress said it had seen none across its partner base as of 10 a.m. ET the same day, while noting that others were reporting attacks. That gap is your patch window.
How the two php2shell bugs work
Both bugs are in PHP's core, not in any application built on it, which is why the affected list reads "everything serving web requests": PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed. Older branches are affected too; they simply get no official fix.
CVE-2026-109618 is the memory bug. PHP handles out-of-memory errors with longjmp(), which abandons the request wherever it happens to be. If an allocation fails while request memory is only partly initialized, that memory is left invalid, and request shutdown then reads it as if it were valid. An attacker forces the failure with multipart requests: no usable Content-Length, unlimited headers per part, nested field names that multiply PHP's work per byte. PHP validated complete remote code execution over HTTP against mod_php with default input and memory limits.
CVE-2026-109619 is the state bug. A PHP worker keeps global state (error, session, object and extension data) that points into memory owned by one request. If a fatal error interrupts the request before that state is reset, the memory is freed while the pointer survives, and the next request on the same worker can use it before initialization replaces it: a use-after-free spread across two HTTP requests, which a crafted heap layout turns into code execution. The confirmed paths run through session upload progress and, on PHP 8.5, fatal error backtraces.
The detail that matters for triage is how each server model handles a failed request startup. Apache mod_php runs the request shutdown procedure unconditionally, even when startup failed, so the attack lands before any application code runs. PHP-FPM exits the child instead, which blocks the easiest path without removing the underlying problem.
| How PHP runs | What the advisories say | Status |
|---|---|---|
| Apache mod_php | Request shutdown runs even when startup fails. Complete RCE validated over HTTP with default limits, before any application code executes. | Exploit confirmed |
| FrankenPHP | Calls request shutdown unconditionally, like mod_php. Likely susceptible to application-independent attacks. | Likely |
| PHP-FPM | Exits the child when startup fails, which blocks the easiest path. Source analysis still supports susceptibility; no complete exploit demonstrated. Exposed to the stale-state bug when the frontend passes PHP_VALUE parameters. | Susceptible |
| LiteSpeed, php-cgi | Named at risk by PHP. LSAPI models FPM; application-specific exploits are likely but unvalidated. | Susceptible |
| PHP 8.1 and older | Affected, with no official updates. Minimal source backports exist for 7.4, 8.0 and 8.1; vendor backports vary. | No official fix |
Sources: PHP advisories GHSA-w8hw-w9fx-j79w and GHSA-6wmf-4rv5-p3rp; php.net security announcement, October 21, 2026.
Attack complexity is rated high, and reliability depends on the build, extensions and allocator layout, so expect repeated attempts rather than one clean shot. User interaction, in CVSS terms, is none.
What to do before the end of the day
Patching is the only complete fix, and the order of operations is the same for an in-house team and an MSP with forty client sites: find the PHP, patch the exposed PHP, then watch the PHP you could not patch.
Inventory first, because PHP hides: WordPress, Drupal, Joomla and Magento sites on shared hosting, cPanel and Plesk, vendor appliances, and Windows software that bundles php.exe or php-cgi.exe without mentioning it.
Then update to 8.5.12, 8.4.27, 8.3.36 or 8.2.35, internet-facing mod_php hosts first. PHP 8.1 and older get no official updates. The security team published minimal source backports for 7.4, 8.0 and 8.1, and some distributions will backport on their own schedule. PHP says the volunteer-maintained remirepo packages will not be updated today.
If a system cannot be patched today, PHP lists configuration changes that cut off the confirmed attack paths without making the install safe:
- Set memory_limit=-1 administratively. Use php_admin_value in the FPM pool or Apache config so applications cannot restore a finite limit, then restart every worker. This removes the controllable memory failure behind CVE-2026-109618, though an underlying allocation failure can still reach the bug. Do not substitute RLIMIT_AS or RLIMIT_DATA; a failed mmap() triggers the vulnerable path.
- Lower post_max_size. 8M with no uploads, 32M with them, upload_max_filesize below it. Enforce decoded request size, part count and header count at the proxy too.
- Disable session upload progress. session.upload_progress.enabled=0 in php.ini or the pool config, then restart the workers. ini_set() and .user.ini apply too late.
- Turn off fatal error backtraces on 8.5. fatal_error_backtraces=0 closes the strongest demonstrated path for CVE-2026-109619.
- Clean up per-request INI settings. Invalid or deprecated php_value and .htaccess directives raise diagnostics before initialization, which is the consumer side of the stale-state bug. Hiding them with @, error_reporting or display_errors changes nothing.
For detection, Florian Roth and the Huntress responders make the same point: exploitation will most likely show up as a PHP worker starting something it should not. Alert when php-fpm, httpd, apache2 or php-cgi launches a shell, an interpreter like python or perl, or curl, wget or nc, and look hard at command lines containing /dev/tcp, fsockopen or mkfifo. On Linux hosts with no endpoint agent, Roth's free process-watcher gives you that visibility in minutes. Its README is candid: it prevents nothing, and code that never spawns a process is invisible to it.
- Inventory every PHP install: web servers, then CMS sites on shared hosting, cPanel and Plesk, appliances, and Windows software bundling php.exe or php-cgi.exe.
- Update to PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35. Internet-facing mod_php hosts go first.
- Where you cannot patch today: memory_limit=-1 via php_admin_value, session.upload_progress.enabled=0, fatal_error_backtraces=0 on 8.5, then restart every worker.
- Put end-of-life PHP behind a WAF or VPN, or take it offline, until it is upgraded.
- Alert on php-fpm, httpd, apache2 or php-cgi launching sh, bash, python, perl, curl, wget or nc. Start process-watcher in observe mode on Linux hosts with no agent.
- Brief the helpdesk, the web team and finance: no patch needs a user's password or a new vendor payment. Any "emergency update" request gets reported.
Sources: php.net security announcement, October 21, 2026; Florian Roth, process-watcher PHP quick start.
This was not phishing, and that matters
We said this about the water-system attacks in August and it applies again: not every attack starts with a person. php2shell has no user in the chain. Nobody clicked, nobody typed a password, and no awareness program on earth changes how Apache handles a failed request startup. Anyone who says training would have stopped this is selling something.
People enter the story in the week after the patch, in two ways.
The first is the pretext. A public emergency with a deadline is the raw material of social engineering, and "your hosting account needs an emergency PHP update" is a lure that writes itself. Expect email to site owners and web admins that quotes the real CVE numbers, links to a lookalike control-panel login and threatens suspension. Expect calls to the helpdesk from "the hosting provider" or "your MSP" asking for SSH or cPanel credentials to apply the fix. The Pink vishing campaign showed how well a phone call plus a plausible IT task works; a patch emergency hands the caller a better script.
Our security team is applying emergency patches for the php2shell vulnerabilities announced by PHP today.
To complete the update on your account, you must verify your control panel credentials2 within 24 hours.
Verify and update now3
Accounts not verified by October 23 will be suspended4 to protect other customers.
- The sender domain is not the provider's. Real notices come from the domain on your invoice.
- Patching happens on the server. No provider needs your password to update PHP.
- The button leads to a login page. Open the control panel from a bookmark instead.
- A deadline plus a suspension threat is the standard pressure pair.
Your host patches the server. Your host does not need your password to do it.
Illustrative example. No real provider, domain or message is depicted.
The second is what a compromised PHP server turns into. A web shell on a server that already hosts your site and sends your transactional email is a phishing kit with a trusted domain and a clean sending reputation. If you find one, assume the server has been used against other people until the logs prove otherwise, and check outbound mail volume as part of the response.
The rule your users need
For everyone: an emergency patch is something IT applies on the server, never something you apply by typing your password into a form. If a message or call says a security update needs your credentials, that request is the incident. Report it.
For the helpdesk and the ops team: nobody patches php2shell over the phone. A caller who needs your credentials to "apply the fix" gets a polite goodbye and a callback to the number on the contract.
Where PhishingBox fits
PhishingBox would not have stopped php2shell, and we would rather say so. Patching stops it. The platform fits the part of this week that does involve people.
- Phishing Simulations can run the "emergency PHP update" pretext against the people who hold hosting, control-panel and server credentials, and the MSP account managers fielding client calls about it.
- Security Awareness Training covers vendor impersonation and credential requests dressed up as maintenance, assigned automatically to whoever types a password into the simulated login.
- KillPhish AI gives the inbox a one-click report button with AI-assisted triage, so the first patch-themed lure that reaches a web admin reaches your security team the same hour.
- Human Risk Management weights risk scores by role, so the ops team with server access is tested first and retrained first, rather than averaged into the company-wide number.
Over 4 million users worldwide train with PhishingBox. See. Score. Secure.
Sources
- PHP: Security advisory: Critical remote code execution vulnerabilities, update now, October 21, 2026
- PHP: Upcoming Critical PHP Security Release, October 20, 2026
- GitHub, php/php-src: GHSA-w8hw-w9fx-j79w, RCE via OOM corruption (CVE-2026-109618), October 21, 2026
- GitHub, php/php-src: GHSA-6wmf-4rv5-p3rp, RCE via stale global state (CVE-2026-109619), October 21, 2026
- watchTowr: PHP RCE FAQ: PHP2Shell CVE-2026-109618 & CVE-2026-109619, published October 20, updated October 21, 2026
- Florian Roth (GitHub): Watching PHP with process-watcher: quick start, October 2026
- Huntress: Rapid Response: php2shell, Leaked Critical PHP Vulnerabilities (CVE-2026-109618 & CVE-2026-109619), updated October 21, 2026
- BleepingComputer: PHP warns admins of two critical flaws, emergency patches coming tomorrow, October 20, 2026
- PhishingBox: Not Every Cyberattack Starts With Phishing: Lessons From Recent Water-System Attacks, August 3, 2026
- PhishingBox: The Phone Call That Beats Your Passkey, July 22, 2026