Sanora.

PHP2Shell: What the 21 October PHP Vulnerabilities Mean and How to Patch Them

Key takeaways

  • Two critical bugs in PHP itself, not in any app. CVE-2026-109618 and CVE-2026-109619 are both rated 9.2 (CVSS v4.0) and can let an attacker run code on the server without logging in. Well-written application code does not protect you.
  • Fixed versions: 8.5.12, 8.4.27, 8.3.36 and 8.2.35, released 21 October 2026. Every version from 5.4 up to 8.5.11 is affected. The PHP project is not shipping new builds for 8.1 or older.
  • Apache with mod_php is the worst case. A working exploit needs a single request and fires before any of your code runs. PHP-FPM is harder to attack but is not safe.
  • There is no complete workaround. Config changes reduce the risk. Only upgrading removes it, and you have to restart every PHP worker for the fix to take effect.
  • Attacks have already started. Exploit attempts were recorded before disclosure, and several security firms reported live attack traffic on release day.

On 21 October 2026 the PHP project shipped emergency releases for two flaws in the language’s core. Researchers named them PHP2Shell. If a server you’re responsible for runs PHP and talks to the internet, patch it today. This guide covers what the flaws are, how bad they get, and the commands to fix them.

Editor’s note: this story is moving quickly. This article reflects what was public as of 22 October 2026. We’ll update it if the guidance changes.

What happened

PHP released versions 8.5.12, 8.4.27, 8.3.36 and 8.2.35 at 14:00 UTC on 21 October. They fix two vulnerabilities, each rated 9.2 (critical) under CVSS v4.0:

Both bugs are in the engine, below WordPress, Laravel, Drupal or your own code. A carefully written application is just as exposed as a careless one, because the vulnerable code runs before your code does, or regardless of it.

The flaws were reported by researchers at Wiz, the security firm Calif, and OpenAI. According to PHP’s own account, the out-of-memory issue was first noticed by a core developer during a 2024 audit. No route to code execution was found then, and the fix stalled. The PHP Foundation has since called that delay “a structural failure” of its decision-making and resources. The vulnerable code paths go back to PHP 5.4, released in 2012.

Who is affected

The official advisory says every PHP installation that serves web requests is at risk. That covers all the common ways of running PHP:

How PHP runsRiskWhy
Apache + mod_phpHighestWorking exploit: one unauthenticated request, triggered before any application code runs. Both CVEs confirmed exploitable.
PHP-FPM (nginx, Apache proxy)HighCVE-2026-109619 was exploited on a normal FPM pool through the session upload-progress feature. That path needs a suitable operation in the app and two requests landing on the same worker. No complete FPM exploit for CVE-2026-109618 has been shown, but source analysis says FPM is susceptible.
php-cgi, FrankenPHP, LiteSpeed (LSAPI)AffectedNamed in the advisory. Exploitation is less well studied, which is not the same as safe.
PHP bundled inside other productsCheck with the vendorControl panels (cPanel, Plesk), network appliances and commercial software often ship their own PHP. Palo Alto Networks has confirmed PAN-OS and Panorama are affected. Fortinet and Cisco are still checking their products.

On versions:

How bad it gets if you don’t patch

The worst case is remote code execution without a login. An attacker sends crafted HTTP requests and ends up running commands as the web server’s user, the account that owns your PHP files, can usually read your .env or wp-config.php, and can reach your database.

From there it is the usual sequence: a web shell, stolen database credentials, a cryptominer, an SEO spam injection, or a foothold for moving deeper into the network. On shared hosting, one compromised account can put other sites on the same machine at risk.

There is a quieter risk too. Researchers showed they could read live worker memory without getting full code execution. That memory can hold data from other users’ requests: session tokens, passwords, API keys, TLS material. An attacker doesn’t need a shell to do damage if they can lift your Stripe key out of RAM.

The people closest to this are treating it as serious:

Is it being exploited?

Yes, at least as attempts. The timeline so far:

At the time of writing, no specific successful break-in had been publicly confirmed. Don’t take much comfort from that. Rapid7 noted multiple signs that the research is being reproduced independently and expects a public exploit soon. Once one is public, mass scanning usually follows within hours.

How to apply the patch

The fix is simple: get onto a patched build, then restart every PHP process. Most people get the first part right and forget the second. A long-running PHP-FPM pool or Apache instance keeps running the old code until it restarts.

Step 1: Find out what you’re actually running

php -v is a start, but it reports the command-line PHP. Your web server may use a different binary, a different version, or both. Check what serves web traffic:

# Command-line PHP
php -v

# PHP-FPM (the binary name varies by distro and version)
php-fpm8.3 -v        # Debian/Ubuntu style
php-fpm -v           # RHEL/Alma/Rocky style

# Is Apache loading mod_php?
apachectl -M 2>/dev/null | grep -i php

# Every PHP process running right now
ps aux | grep -E 'php|httpd|apache2' | grep -v grep

On WordPress, Tools → Site Health → Info → Server shows the PHP version the site is actually using. Also check containers, CI images, staging servers and that old VM nobody owns. CISA’s first recommendation is a full inventory, because PHP turns up in places people forget about.

Step 2: Upgrade

Use your normal package source. Linux distributions and LTS vendors were given the patches before the public release, so packages should be available. One important detail: distribution packages often backport the fix and keep an older-looking version number. Debian’s advice is to check the package changelog for the CVE ID, not the version string.

Debian / Ubuntu (including the popular ppa:ondrej/php builds):

sudo apt update
apt list --upgradable 2>/dev/null | grep -i php
sudo apt install --only-upgrade 'php8.3*'    # match your installed version

# Confirm the fix is in the package
apt changelog php8.3-common | grep -m1 -E 'CVE-2026-10961[89]'

RHEL / AlmaLinux / Rocky / Fedora:

sudo dnf upgrade 'php*'

# Confirm the fix is in the package
rpm -q --changelog php-common | grep -m1 -E 'CVE-2026-10961[89]'

If you use the Remi repository (rpms.remirepo.net), note that it is run by volunteers and had no updates on release day. PHP’s advice was to switch to distribution packages or build from source if you need the fix immediately. Check whether Remi has caught up before you assume you’re covered.

Docker: pull the patched official image tag (for example php:8.3.36-fpm), rebuild every image based on it, and redeploy. Pulling a new base image does nothing for containers that are already running.

docker pull php:8.3.36-fpm
docker build --pull -t my-app:patched .
# then redeploy and confirm:
docker exec <container> php -v

Windows: download the patched build from php.net, replace the installation, and restart IIS or Apache.

From source: download the patched tarball from php.net. On 7.4, 8.0 or 8.1, apply the minimal backport linked from the advisory. Treat that as a stopgap until you move to a supported branch.

Managed platforms: on Google Cloud, App Engine Standard (PHP 8.2+) is being updated automatically. Cloud Run is updated automatically only if automatic base-image updates are on. App Engine Flexible and GKE need a rebuild and redeploy. Other managed hosts vary, so check your provider’s status page or ask support.

Shared hosting, cPanel or Plesk: most of this is your host’s job, but confirm it was done. Ask them directly: “Has the 21 October 2026 PHP security release been applied to my server, and which PHP version is my site on?” If you’re on 8.1 or older, use the panel’s PHP version selector to move to 8.2 or newer, after testing on a staging copy, because old themes and plugins can break.

Step 3: Restart everything that runs PHP

# PHP-FPM (adjust the service name to your version and distro)
sudo systemctl restart php8.3-fpm        # Debian/Ubuntu
sudo systemctl restart php-fpm           # RHEL family

# Apache (needed for mod_php)
sudo systemctl restart apache2           # Debian/Ubuntu
sudo systemctl restart httpd             # RHEL family

A reload is not enough here. You want every worker process replaced. Afterwards, run the ps command from step 1 again and check that no process started before the upgrade is still alive.

Step 4: Check the new memory behaviour

The patch changes how PHP handles running out of memory. Instead of jumping straight out of the request, PHP now handles a normal memory-limit overrun at the next safe point. It also adds a second, higher hard limit: if memory use reaches it, the process exits immediately and shutdown functions don’t run. Most applications won’t notice. If you have batch jobs or import scripts that regularly push past memory_limit, test them, and review memory_limit and post_max_size against what your application really needs.

If you can’t patch today

Sometimes the upgrade is blocked by a vendor appliance, an ancient application, or a change freeze. The advisory lists measures that reduce exposure. To be clear, they do not make you safe. Use them for hours or days, not weeks.

; php.ini, or an FPM pool / Apache config the application can't override
session.upload_progress.enabled = 0   ; blocks the confirmed CVE-2026-109619 session path
fatal_error_backtraces = 0            ; PHP 8.5 only
memory_limit = -1                     ; removes the controllable OOM trigger (CVE-2026-109618)
post_max_size = 8M                    ; 32M if you genuinely need uploads
; keep upload_max_filesize below post_max_size

Some details that are easy to miss:

If none of that is possible and the system faces the internet, follow CISA and the NCSC: take it offline until it’s patched.

Check you weren’t hit before you patched

Patching closes the hole. It doesn’t remove anyone who got in before you closed it. Exploit attempts predate the disclosure, so a quick look back is worth doing on anything that was exposed. Signs researchers and CISA have flagged:

A quick first pass on a Linux host:

# PHP files changed in the last 10 days under the web root
find /var/www -name '*.php' -mtime -10 -printf '%TY-%Tm-%Td %p\n' | sort

# Memory-limit errors in recent logs
grep -i 'allowed memory size' /var/log/php*-fpm.log /var/log/apache2/error.log 2>/dev/null | tail

If anything looks wrong, assume the worst: rotate database passwords, API keys and application secrets, invalidate sessions, and rebuild from a known-good source rather than trying to clean the server in place. Because of the memory-disclosure angle, rotating high-value secrets is reasonable even if you find nothing.

The checklist

  1. List every system that runs PHP, including containers, appliances and control panels.
  2. Upgrade to 8.5.12, 8.4.27, 8.3.36 or 8.2.35, or a vendor package whose changelog lists both CVEs.
  3. Restart every PHP-FPM pool and Apache instance, and confirm no old processes remain.
  4. If you’re on 8.1 or older, plan the move to a supported branch now. 8.2 itself goes end-of-life on 31 December 2026.
  5. Where you can’t patch yet, apply the interim settings, turn on WAF blocking, or take the system offline.
  6. Look for signs of compromise, and rotate secrets on anything that was exposed.

A note on what this says about the web

It’s worth stepping back for a moment. One of the two bugs was spotted in 2024 and stalled because a small, donation-funded team couldn’t agree on a fix that wouldn’t break something else. When it was finally reported in full, AI-assisted research had turned decade-old weaknesses into working exploits in weeks. Calif and Wiz both credited AI models with speeding up the work.

That combination of under-resourced core infrastructure and much faster exploit development is going to happen again. The practical lesson for anyone running software is to be able to patch your whole stack in hours, not weeks: know where PHP runs, keep it on supported branches, and make “rebuild and redeploy” a routine operation rather than a project.

Sources

Need a hand patching?

If you have PHP sites, servers or containers and you’re not sure what’s exposed, we can audit, patch and verify them with you, and help you get off end-of-life PHP for good.

Talk to us →

How this post was written: drafted with AI assistance, then reviewed, fact-checked and edited by Sanora Technologies. Product details reflect our own apps as of the publish date.

PHP2Shell CVE-2026-109618 CVE-2026-109619 PHP vulnerability PHP security update PHP 8.4.27 PHP 8.3.36 remote code execution mod_php PHP-FPM WordPress security

FAQ

Common questions

What is PHP2Shell?

PHP2Shell is the name given to two critical vulnerabilities in the PHP runtime, CVE-2026-109618 (“RCE via OOM corruption”) and CVE-2026-109619 (“RCE via stale global state”). Both were patched on 21 October 2026. Both can allow an unauthenticated attacker to execute code on a web server that runs PHP, and to read memory that may contain passwords, tokens and keys.

Which PHP versions fix PHP2Shell?

PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35. If you install PHP from a Linux distribution, your package may contain the fix under an older-looking version number, so check the package changelog for the CVE IDs instead of the version string.

Is PHP 7.4, 8.0 or 8.1 affected, and will it be patched?

Yes, they are affected. The PHP project no longer releases builds for these end-of-life branches, but it has published minimal source backports for 7.4, 8.0 and 8.1. Some Linux distributions and long-term-support vendors ship patched packages. Otherwise, upgrade to PHP 8.2 or newer. Note that 8.2 itself reaches end of life on 31 December 2026.

Can I just change a php.ini setting instead of upgrading?

No. The official advisory is explicit: there are no complete mitigations and updating is the only safe choice. Disabling session.upload_progress.enabled, enforcing memory_limit=-1 and tightening request limits block the known attack paths, but not every variant. Use them only to buy time until you can upgrade.

I use shared hosting or managed WordPress. What should I do?

Check your PHP version in WordPress under Tools → Site Health → Info → Server, then ask your host directly whether the 21 October 2026 PHP security release has been applied to your server. If you are on PHP 8.1 or older, ask to move to a supported version, and test on a staging copy first. Do not edit server PHP settings yourself on shared hosting.

Does a web application firewall protect me from PHP2Shell?

Partly. Cloudflare and Google Cloud Armor both shipped rules for the known exploit patterns, and Cloudflare enabled them on free plans too. Cloudflare has already reported attackers changing their payloads to get past those rules. A WAF gives you some time. It does not replace the patch.

Sanora Technologies

Got a product to build?

We build web apps, mobile apps, SaaS platforms and AI agents for founders and businesses — MVPs in as little as a week, and you work directly with the person writing the code.