---
id: 10297
title: "PHP2Shell: finding and patching affected PHP"
cve: null
cvss: null
severity: unknown
vendor: null
product: null
affected_versions: null
source_domain: projectdiscovery.io
source_url: "https://projectdiscovery.io/research/php2shell"
published_at: "2026-10-21T00:00:00Z"
snapshot_at: "2026-10-26T03:06:00Z"
archived_by: "Phying News (https://phying.com/item/10297)"
lang: en
---

# PHP2Shell: finding and patching affected PHP

*Published on: October 21, 2026 · Source: [ProjectDiscovery Research](https://projectdiscovery.io/research/php2shell)*

- [Community resources](#community-resources)
- [PHP on the internet](#php-on-the-internet)
- [Why PHP is hard to find](#why-php-is-hard-to-find)
- [Find and patch PHP](#find-and-patch-php)
- [Prompts for AI agents](#prompts-for-ai-agents)
- [Upgrade](#upgrade)
- [SecureTheWeb.org](#securetheweborg)
- [References](#references)

On October 21, a large part of the internet went into maintenance mode. DeviantArt and Pokémon Home went offline, and Wikimedia took many of the services behind Wikipedia offline. Government agencies in the Netherlands, Finland and Denmark took public sites down, along with the Port of Rotterdam and several Dutch hospitals. Hosting providers ran emergency maintenance through the night and switched off PHP features across shared servers while they waited for packages.

The cause is two critical bugs in the PHP runtime, CVE-2026-109618 and CVE-2026-109619, each rated CVSS 9.2, that allow unauthenticated code execution and can leak worker memory, including passwords, tokens and API keys from other requests. The CVE IDs leaked two days before the planned release, so the PHP team shipped a day early, and Cloudflare reported attack traffic before the fix was out. CISA, the NSA, the UK NCSC and CERT-EU all said to patch now and, where that is not possible, to take PHP systems offline or off the public internet until you can.

The patch is a package upgrade and a restart. Finding every PHP runtime is the hard part. CISA's alert says it plainly: PHP “is often a component of other software and prevalence may not be directly observable.”

## Community resources

Defenders are sharing what they have:

- [Cloudflare](https://blog.cloudflare.com/php-vulnerabilities-waf-protection/) deployed WAF rules to every plan, including free, hours before disclosure.
- [Corelight](https://github.com/corelight/php2shell-detect) open-sourced Zeek and Suricata detections, and [Elastic](https://www.elastic.co/security-labs/threat-command/php2shell-php-rce-detection) published rules for what attackers do after code execution.
- [Hostinger](https://www.hostinger.com/blog/protecting-php2shell/) and [Laravel](https://laravel.com/blog/php-critical-vulnerability-response-updates) published update steps for customers who manage PHP on their own servers, such as Hostinger VPS and Laravel Forge.
- ProjectDiscovery published a [Nuclei template](https://github.com/projectdiscovery/nuclei-templates/blob/main/http/cves/2026/CVE-2026-109618.yaml) for version checks, and [Neo](https://go.projectdiscovery.io/php2shell) has the full find-and-patch flow pre-built to discover and scan your assets for free.
- [SecureTheWeb.org](https://securetheweb.org/) is notifying the operators of affected services directly.
- Fake exploit repositories are circulating. [JFrog](https://research.jfrog.com/post/php2shell-all-you-need-to-know-about-cve-2026-109618-and-cve-2026-109619/) found fake PoCs on GitHub shared as pranks. Run public PoCs only in an isolated lab, if at all.

## PHP on the internet

PHP serves 69.3% of websites whose server-side language is known, according to [W3Techs](https://w3techs.com/technologies/comparison/pl-php%2Cpl-static). On October 21, Shodan returned 1,677,546 service records advertising an explicit PHP version. The bug is in the runtime, so every application on an affected PHP is in scope: WordPress, Drupal, Magento, Laravel and custom code alike.

> **Key Exposure Metrics:**
> - **69.3%** of websites with a known server-side language use PHP (W3Techs).
> - **1,677,546** Shodan service records advertised an explicit PHP version on October 21.

The services most at risk are the ones that run for years without attention. Many of them sit next to the systems that matter most: the firewall, the phone system, the billing database, the mail server.

| Where long-lived PHP runs | Examples |
| --- | --- |
| Hosting servers | cPanel and Plesk servers, and every site they host |
| Network monitoring | Zabbix, Cacti, Nagios XI, LibreNMS |
| Firewalls and phones | pfSense, OPNsense, FreePBX |
| Mail and files | Roundcube, Nextcloud, ownCloud |
| Database admin | phpMyAdmin, Adminer |
| Billing, CRM, helpdesk | WHMCS, SuiteCRM, vTiger, osTicket, GLPI |
| Learning and wikis | Moodle, MediaWiki |

## Why PHP is hard to find

- **Non-standard ports.** Admin panels listen on 2083, 2087, 8080, 8443, 8880 and other ports that a scan of 80 and 443 misses.
- **Sub-paths.** A host with a static site on `/` can run phpMyAdmin on `/phpmyadmin/` or Roundcube on `/webmail/`.
- **Hidden versions.** Setting `expose_php = Off`, or a proxy or CDN rule that strips the `X-Powered-By` header, hides the PHP version. Many PHP services show no version at all.
- **Appliances and panels.** Firewalls and hosting control panels often ship their own PHP, so the fix arrives as a vendor update. Until it is installed, the admin interface is vulnerable wherever it can be reached. InMotion closed its CWP admin ports for this reason: the panel runs on PHP and had no fix yet.
- **Containers.** An image built on an old `php:` base keeps that PHP until someone rebuilds it. BIT.nl patched every server it manages on October 21 and noted that containers maintained by customers had not been updated.
- **Forgotten domains.** Acquisitions, agency-built campaign sites, staging copies and test servers live outside the main inventory.

## Find and patch PHP

Five steps, each feeding the next. The commands use free ProjectDiscovery tools, plus `jq` for step 3.

> **Workflow:**
> 1. **List assets** (domains + IP ranges) → 2. **Find web services** (every port) → 3. **Mark PHP** (headers + cookies) → 4. **Check versions** (Nuclei template) → 5. **Patch + restart** (confirm on host)
>
> *Note: Installing the fixed package doesn't change a worker that is already running: the old binary keeps serving until the restart.*

### 1. List everything you own

Put every root domain in `domains.txt`: product, marketing, regional, acquired, and the ones agencies registered for you. Put public IP ranges and cloud egress addresses in `ranges.txt`.

### 2. Find every web service, on every port

*(writes `web.txt`)*

```bash
subfinder -dL domains.txt -all -silent | cat - domains.txt | dnsx -silent > hosts.txt
cat ranges.txt >> hosts.txt
naabu -l hosts.txt -p 80,443,2082,2083,2086,2087,2095,2096,8000,8080,8443,8880,8888,9443 -silent > open.txt
httpx -l open.txt -silent > web.txt
```

For the hosts that matter most, scan every port with `-p -`. If port 9000 answers from the internet, check what is listening. It is PHP-FPM's default FastCGI port, and the official `php-fpm` Docker images listen on it on every interface. If it is PHP-FPM, close it.

### 3. Mark the services that run PHP

Probe the root and the paths where PHP apps usually live, then keep every response that shows PHP: an `X-Powered-By` or `Server` header naming PHP, or a `PHPSESSID` cookie.

*(writes `php.txt`)*

```bash
httpx -l web.txt -silent -td -irh -j -o probe.json \
  -path /,/index.php,/phpmyadmin/,/webmail/,/roundcube/,/zabbix/,/cacti/,/glpi/,/wp-login.php
jq -r 'select((.tech // [] | tostring | test("PHP")) or (.header | tostring | test("PHP/|PHPSESSID"))) | .url' \
  probe.json | sort -u > php.txt
```

`php.txt` is your PHP inventory. Services that show PHP without a version go straight to step 5.

### 4. Check the advertised versions

The [CVE-2026-109618 Nuclei template](https://github.com/projectdiscovery/nuclei-templates/blob/main/http/cves/2026/CVE-2026-109618.yaml) reads the version from the `X-Powered-By` header and flags PHP 5.4 and later below the fixed releases. It sends one ordinary GET per URL and attempts no exploitation. It is on the `nuclei-templates` main branch and not yet in a release, so download it first:

*(writes `affected.txt`)*

```bash
curl -sO https://raw.githubusercontent.com/projectdiscovery/nuclei-templates/main/http/cves/2026/CVE-2026-109618.yaml
nuclei -t CVE-2026-109618.yaml -l php.txt -o affected.txt
```

### 5. Confirm on the host, patch, restart, verify

The banner is a lead. The host is the answer. On each server, check the installed PHP and what is actually running:

*(run on each server)*

```bash
for b in /usr/bin/php* /usr/sbin/php-fpm* /usr/local/bin/php /usr/local/sbin/php-fpm; do [ -x "$b" ] && echo "$b: $("$b" -v 2>/dev/null | head -1)"; done
dpkg -l 'php*' | grep ^ii          # Debian, Ubuntu
rpm -qa 'php*'                      # RHEL, Rocky, Alma
ps -eo pid,args | grep -E 'php-fpm|php-cgi|lsphp|frankenphp|httpd|apache2' | grep -v grep
```

Patch Apache `mod_php` hosts first: php.net rates them highest risk, because one unauthenticated request can trigger the attack before any application code runs. Upgrade to a fixed release, then restart PHP-FPM, Apache and LiteSpeed. For containers, rebuild the image on a fixed `php:` base and redeploy it. This lists processes still running a PHP build that was replaced on disk; it should print nothing:

*(should print nothing)*

```bash
sudo grep -lE '(php|libphp).*\(deleted\)' /proc/[0-9]*/maps 2>/dev/null
```

Finish with one request through the normal production route. Where the version header is exposed, confirm it shows the fixed release. Elsewhere, confirm with `php -v` and `php-fpm -v` on the host.

## Prompts for AI agents

Most coding agent apps and tools already know how to use ProjectDiscovery tools. Whether you use Claude Code, Codex or OpenCode, lean on what your app does best, like goal mode or dynamic workflows, and pick the strongest model you have access to, so one prompt can work through your whole estate. Start with a short setup prompt, then give your agent the objective.

**Install the tools:**
```text
Install the ProjectDiscovery tools with pdtm (github.com/projectdiscovery/pdtm) and confirm subfinder, dnsx, naabu, httpx and nuclei run.
```

**Map internet-facing PHP:**
```text
Find every internet-facing service that runs PHP across the domains in domains.txt, including admin panels on non-standard ports and apps under sub-paths. Use whatever works: ProjectDiscovery tools, Nuclei templates, a browser, manual checks. For each service, find the PHP version and whether it is below the fixed releases (8.2.35, 8.3.36, 8.4.27, 8.5.12). Return one table: URL, application, PHP version or unknown, affected (yes, no, unknown).
```

**Find PHP in code and infrastructure:**
```text
Search our repositories for everything that builds or deploys PHP: Dockerfiles with FROM php:, installs of php-fpm or libapache2-mod-php, Helm charts, Terraform and Ansible roles. List each with the PHP version it pins, the service it deploys and the team that owns the repository. Flag every version below 8.2.35, 8.3.36, 8.4.27 or 8.5.12, and every PHP 8.1 or older.
```

**Check one server:**
```text
On this Linux server, list every PHP binary, PHP package and running PHP process (PHP-FPM, Apache mod_php, php-cgi, LiteSpeed, FrankenPHP), plus PHP inside running containers. For each, give the version and whether it is below the fixed release for its branch: 8.2.35, 8.3.36, 8.4.27, 8.5.12. Flag any process whose PHP binary or libphp module shows as deleted in /proc/<pid>/maps, since it needs a restart. Read only; change nothing.
```

Our open-source tools work with any agent or setup, and [Neo](https://go.projectdiscovery.io/php2shell) runs this whole flow for free if you would rather not set anything up.

## Upgrade

| PHP branch | First fixed release |
| --- | --- |
| 8.2 | 8.2.35 |
| 8.3 | 8.3.36 |
| 8.4 | 8.4.27 |
| 8.5 | 8.5.12 |

- Distribution, hosting and LTS packages can carry the fix under an older version string. Confirm the changelog names both CVEs.
- PHP 8.1 and older: every release back to 5.4 is affected. Move to a supported branch, or install a vendor package that backports both fixes. If you build from source, PHP published minimal source backports for 7.4, 8.0 and 8.1.
- Appliances: apply the vendor's update as soon as it ships, and keep the admin interface off the internet until then.
- Anything you cannot patch today: remove public access until the upgrade lands. [php.net](https://www.php.net/index.php#2026-10-21-5) lists temporary settings, such as `session.upload_progress.enabled=0`, that reduce exposure on specific paths. They do not make a server safe, and they only take effect in `php.ini` or the FPM pool after a worker restart.
- If an affected server was reachable from the internet before you patched, assume secrets in its memory were exposed. Rotate its database passwords, API keys and session signing keys, and check it for signs of compromise.

## SecureTheWeb.org

Alongside this guide, we are also launching [SecureTheWeb.org](https://securetheweb.org/), a notification service for critical vulnerabilities that affect the internet at scale. It runs on [Chaos](https://chaos.projectdiscovery.io/), our internet-wide dataset of exposed services, updated in real time and continuously enumerated to cover legacy infrastructure as well as modern. When an advisory like this one lands, SecureTheWeb matches the affected versions against Chaos and emails the `security@` inbox of every domain running one, with the fixed release and the steps to patch. These two CVEs are the first event it covers, and those emails are already going out, since attack traffic was flowing before the fix shipped. Over the coming months we will run more of our tools against Chaos at scale to enrich it and map exposed services better, and we will keep the data available for everyone to use in their own research and remediation. This will matter more as the exploitation capabilities of AI agents keep rising.

## References

- [PHP security release and remediation guidance](https://www.php.net/index.php#2026-10-21-5)
- [CVE-2026-109618 advisory](https://github.com/php/php-src/security/advisories/GHSA-w8hw-w9fx-j79w)
- [CVE-2026-109619 advisory](https://github.com/php/php-src/security/advisories/GHSA-6wmf-4rv5-p3rp)
- [Technical research on both CVEs from Wiz](https://www.wiz.io/blog/php2shell-php-rce)
- [Nuclei template CVE-2026-109618](https://github.com/projectdiscovery/nuclei-templates/blob/main/http/cves/2026/CVE-2026-109618.yaml)
- The PHP advisories credit lcfr-hax, sagitzadik-wiz, tomash-areion and amyb-oai for the reports, and arnaud-lb, iluuu1994, bukka and ndossche for the fixes.

---
> 📦 **Full-Text Markdown Snapshot** archived by [Phying News](https://phying.com/item/10297) · Original source: [projectdiscovery.io](https://projectdiscovery.io/research/php2shell)
