# PHP2Shell: Why Pieter Levels Took His Sites Offline—and How to Patch PHP

Why Pieter Levels shut down his sites over PHP2Shell, which PHP versions fix the flaws, and how to verify Ubuntu, PHP-FPM and Docker updates.

Canonical URL: https://aiidelist.com/blog/php2shell-pieter-levels-php-security-patch

Language: en

Published: 2026-10-23

Updated: 2026-10-23

## Key Takeaways

- **PHP2Shell refers to two critical PHP runtime vulnerabilities:** CVE-2026-109618 and CVE-2026-109619. Both carry a CVSS v4.0 score of **9.2** and can enable unauthenticated remote code execution under applicable conditions.
- **Pieter Levels temporarily disconnected his websites and VPS servers**, then announced their return after Ubuntu published backported fixes. His statements describe a precautionary shutdown, not a confirmed breach.
- **Updating WordPress, a framework or a plugin does not replace patching PHP.** The affected component is the runtime executing the application.
- **A successful update requires verification:** identify the actual web runtime, install its vendor-approved fix and ensure running workers load the updated code.
- **Attack attempts predated public disclosure.** Amazon traced activity to October 17, 2026, while distinguishing observed attempts from proven compromise of production systems. 

**Updated October 23, 2026.** Package versions below identify the published fixes for this incident; later vendor-supported security releases may supersede them.

## Why Pieter Levels Took His Websites Offline

On October 21, Pieter Levels published a [precautionary shutdown announcement](https://levels.io/disconnected-sites-until-php-patch), explaining that he had disconnected his websites and VPS servers while waiting for PHP patches. That announcement documents an operational decision to reduce exposure during the release window. It does not establish that an attacker had accessed his systems. 

In his subsequent [restoration announcement](https://x.com/levelsio/status/2112943822481318122), Levels wrote, “Everything is back up,” and thanked Ubuntu and the PHP team for the rapid availability of backported fixes. 

The practical lesson is about containment. When an exposed runtime has a critical flaw and a suitable fix is not yet deployable, temporarily removing access can reduce the opportunity for exploitation.

For operators following that approach, the implementation matters: a maintenance screen generated by the vulnerable PHP application still invokes PHP. A stronger containment design serves a static response at the proxy or edge and prevents public requests from reaching the affected runtime, including through alternate origin addresses.

## What Is PHP2Shell?

PHP2Shell groups two related memory-safety problems in PHP’s handling of failed requests and persistent worker state.

| Vulnerability | What goes wrong | Security consequence |
|---|---|---|
| CVE-2026-109618 | An out-of-memory interruption can leave internal request structures partially initialized; cleanup may subsequently use them | Memory corruption and possible remote code execution |
| CVE-2026-109619 | A worker retains references to memory belonging to an earlier request after that memory is freed | Use-after-free, memory disclosure and possible remote code execution |

The official [OOM corruption advisory](https://github.com/php/php-src/security/advisories/GHSA-w8hw-w9fx-j79w) explains that PHP’s abrupt error-handling path can interrupt operations before their internal state is safe. The [stale global state advisory](https://github.com/php/php-src/security/advisories/GHSA-6wmf-4rv5-p3rp) describes how a later request handled by the same worker can encounter invalid references left behind by an earlier request. 

**Unauthenticated RCE does not mean automatic root access.** The demonstrated execution occurs with the web worker’s privileges. Those privileges determine the immediate reach of an attacker—for example, whether the process can read application secrets or modify deployed files. 

A further complication is that data exposure can occur without a completed code-execution chain. Wiz demonstrated disclosure of PHP process memory containing sensitive information. Consequently, an investigation focused only on newly created malicious files can miss other forms of impact. 

## The Disclosure and Attack Timeline

| Date | Confirmed development |
|---|---|
| 2024 | PHP developers identified early signs of the OOM problem while addressing findings from an external security audit |
| August 11, 2026 | Calif reported a working RCE path associated with that underlying problem |
| October 17 | Amazon’s MadPot telemetry recorded an exploitation attempt later associated with PHP2Shell |
| October 20 | CVE identifiers circulated prematurely; PHP advanced the planned release by one day |
| October 21 | PHP published emergency security releases; Levels publicly described his precautionary shutdown |
| After Ubuntu’s fixes became available | Levels announced that his sites were back online |

The PHP Foundation’s [disclosure account](https://thephp.foundation/blog/2026/10/21/todays-php-security-release-and-how-were-strengthening-php-security/) documents the earlier findings and disrupted release schedule. Amazon’s [threat-intelligence report](https://aws.amazon.com/blogs/security/amazon-threat-intelligence-identifies-php2shell-exploitation-prior-to-public-disclosure-in-madpot/) supplies the earlier attack date. 

Amazon explicitly cautioned that it was unclear whether the early attempts would have succeeded against real-world systems. **Observed attack traffic, a reproducible exploit and a confirmed production breach are different findings.**

## Which PHP Deployments Need Attention?

PHP’s [security announcement](https://www.php.net/archive/2026.php) covers installations serving web requests, including Apache with `mod_php`, PHP-FPM, CGI, FrankenPHP and LiteSpeed. It identifies `mod_php` as particularly exposed because a demonstrated attack can execute before application code begins. 

For deployment planning, use the following ownership map:

| Deployment | Component to verify | Common oversight |
|---|---|---|
| WordPress or another PHP CMS | Hosting provider’s PHP runtime | Updating the CMS while leaving PHP unchanged |
| Nginx with PHP-FPM | Every active FPM version and service | Updating only the command-line interpreter |
| Apache with `mod_php` | PHP module package and Apache processes | Installing packages without restarting Apache |
| Docker or Kubernetes | PHP inside each deployed image | Updating the host while old containers continue running |
| Managed PHP platform | Provider advisory and deployment policy | Assuming every managed service patches automatically |
| Static frontend with a PHP API | The API’s runtime | Checking only the frontend hosting platform |

Nginx does not establish immunity. The stale-state advisory reports a validated session-lifecycle RCE path against FPM as well as `mod_php`. Exploit paths and prerequisites vary across deployments. 

## Which PHP Versions Fix PHP2Shell?

The upstream PHP project published these security releases on October 21:

| PHP branch | First upstream release fixing both vulnerabilities |
|---|---|
| PHP 8.5 | `8.5.12` |
| PHP 8.4 | `8.4.27` |
| PHP 8.3 | `8.3.36` |
| PHP 8.2 | `8.2.35` |

For PHP 8.1 and earlier, normal upstream release support has ended. PHP nevertheless provided minimal source backports for 7.4, 8.0 and 8.1 for builders and downstream maintainers. These are not equivalent to restoring normal support for those branches. Use a maintained vendor package or migrate to a supported branch. 

## Why Ubuntu Can Be Patched While Showing an Older PHP Version

Ubuntu can apply a security correction to the PHP version shipped with a distribution instead of replacing it with the latest upstream release. This process is called **backporting**.

The [Ubuntu USN-8948-1 notice](https://ubuntu.com/security/notices/USN-8948-1) lists these fixed package versions:

| Ubuntu release | PHP branch | Published fixed package version |
|---|---|---|
| 26.10 | 8.5 | `8.5.9-0ubuntu2.1` |
| 26.04 LTS | 8.5 | `8.5.4-0ubuntu1.5` |
| 24.04 LTS | 8.3 | `8.3.6-0ubuntu0.24.04.13` |
| 22.04 LTS | 8.1 | `8.1.2-1ubuntu2.28` |

Therefore, the upstream-looking number `8.3.6` alone cannot determine whether Ubuntu 24.04 is patched. The complete package revision and its origin matter. 

The separate [USN-8948-2 notice](https://ubuntu.com/security/notices/USN-8948-2) also lists fixes for older Ubuntu releases. For example, Ubuntu 20.04’s PHP 7.4 fix is `7.4.3-4ubuntu2.29+esm5`, delivered through Ubuntu Pro. Older releases have their own coverage requirements. 

**Do not apply Ubuntu’s package thresholds to unrelated builds.** A third-party repository, control panel or custom installation requires its own vendor’s patch evidence.

## How to Check and Patch an Ubuntu PHP Server

The following workflow illustrates an Ubuntu 24.04 server using PHP 8.3-FPM. Adapt package and service names to the deployment.

**1. Identify the installed runtime and package origin.**

```bash
cat /etc/os-release
php -v
systemctl list-units --type=service --all 'php*-fpm.service'
apt-cache policy php8.3-fpm php8.3-cli php8.3-common
```

Read `Installed` as the current package and `Candidate` as the version available from configured repositories. If the package is absent, that result does not establish that PHP is absent: inspect containers, custom installations and hosting control panels.

Map each virtual host’s FastCGI destination to the FPM service that actually receives its requests. A server can have a patched CLI and an older web runtime simultaneously.

FPM also supports pool-specific settings, so inspecting CLI configuration does not establish a web pool’s effective configuration. The [FPM configuration manual](https://www.php.net/manual/en/install.fpm.configuration.php) documents these overrides. 

**2. Refresh package metadata and inspect the proposed update.**

```bash
sudo apt update
apt-cache policy php8.3-fpm php8.3-cli php8.3-common
apt-mark showhold
sudo apt-get --simulate upgrade
```

Investigate held packages or a candidate that lacks the fix. Repository configuration and package pinning can prevent the intended update from being selected.

**3. Apply the reviewed updates.**

```bash
sudo apt upgrade
```

Ubuntu’s [incident guidance](https://ubuntu.com/blog/php2shell-vulnerability-fixes-available) recommends updating packages and restarting applications that use PHP. Package installation alone can leave existing processes running older code. 

**4. Restart the service that executes PHP.**

For the example FPM deployment:

```bash
sudo systemctl restart php8.3-fpm
systemctl is-active php8.3-fpm
```

For Apache using `mod_php`:

```bash
sudo systemctl restart apache2
systemctl is-active apache2
```

Select the command matching the architecture. Restarting Nginx alone does not replace PHP-FPM workers.

**5. Record patch evidence and test application behavior.**

```bash
dpkg-query -W php8.3-fpm php8.3-cli php8.3-common
systemctl status php8.3-fpm --no-pager
sudo journalctl -u php8.3-fpm --since '15 minutes ago' --no-pager
```

Check dynamic pages, authentication, uploads, payment callbacks and scheduled processing as applicable. A cached homepage is insufficient evidence that PHP is healthy.

For multiple servers, retain four pieces of evidence per instance: **package provenance, fixed version, process replacement and application health**. Avoid marking an entire deployment complete after checking only one node.

## Docker and Managed Platforms: Rebuilds Must Reach Production

Docker images preserve the software included when they were built. Updating a host package does not update PHP embedded in a container.

For a custom application image, first select a patched base version or digest, then rebuild:

```bash
docker build --pull --no-cache -t php-app:php2shell-patched .
```

Docker’s [build guidance](https://docs.docker.com/build/building/best-practices/) explains the distinction: `--pull` checks for a newer base image, while `--no-cache` reruns build steps. Neither flag makes an explicitly pinned vulnerable version safe. 

Deploy the resulting image and verify every running replica. Update deployment templates as well, so scaling or rollback does not reintroduce the previous image.

Managed hosting also requires a service-specific check. [Google Cloud’s incident guidance](https://cloud.google.com/blog/products/identity-security/responding-to-core-php-vulnerabilities-cve-2026-109618-cve-2026-109619) distinguishes automatic updates from services requiring redeployment. Custom container images remain the customer’s responsibility; Cloud Run behavior depends on whether automatic base-image updates are enabled. 

Ask a hosting provider to confirm the runtime serving the site, the fix covering both CVEs and whether active processes or instances have been replaced.

## Does Cloudflare Protect Against PHP2Shell?

Cloudflare reports deploying default protections for free and paid WAF customers from October 21 at 03:02 UTC. Its [PHP2Shell announcement](https://blog.cloudflare.com/php-vulnerabilities-waf-protection) also describes detection using both request and response signals, alongside continuing adjustments as attack payloads changed. Cloudflare explicitly instructs customers to patch PHP despite these protections. 

Operationally, verify that:

- Relevant hostnames actually pass through the protective proxy.
- Applicable managed rules are enabled with the intended action.
- Exceptions or bypass rules do not exclude sensitive routes.
- Alternate hostnames and direct origin access do not provide an unprotected route.

**A WAF event records a detection or action; it does not certify the origin’s patch status.** Keep runtime remediation and edge protection as separate items in the incident checklist.

## What If PHP Cannot Be Patched Immediately?

Temporarily restrict access to the affected service and follow the current PHP advisory. Its configuration mitigations address particular paths, rather than providing a complete substitute for updating.

Examples include disabling session upload progress and, on PHP 8.5, fatal-error backtraces. Relevant changes must apply early enough in request processing and require worker restarts. 

One easily misunderstood recommendation is `memory_limit=-1`. It removes the predictable PHP memory-limit failure used by certain OOM attacks, but underlying allocation failures remain possible. Removing that limit also requires deliberate resource controls. It should not be copied as a universal hardening setting. 

## How to Investigate Possible Earlier Exploitation

Amazon recommends beginning the review **at least as early as October 17**, examining suspicious requests, unexpected process execution and file modifications. Its published IP indicators involve shared anonymization infrastructure, so an IP match alone does not establish compromise. 

A practical investigation should correlate:

- Proxy and web-server requests with PHP worker errors or crashes.
- Unexpected child processes with the account running the application.
- File changes with deployment records and approved maintenance.
- Unusual outbound connections with application behavior.
- Suspicious activity with secret access and authentication events.

Ordinary access logs frequently omit request bodies, limiting retrospective inspection of multipart fields. Preserve existing telemetry rather than assuming a missing payload proves there was no attack.

If evidence indicates compromise, treat patching as one part of incident response: isolate affected instances, preserve evidence, determine exposed credentials and restore from a trusted deployment. A runtime patch does not remove persistence already established by an attacker.

## How AI Changed the PHP2Shell Investigation

Wiz reports using **Wiz Atlas, Gemini 4 Argon and GPT-5.6 Sol** during vulnerability analysis, exploit development and patch validation. Its research demonstrated attacks against WordPress, Drupal and Joomla deployments, while emphasizing that the underlying flaws reside in PHP itself. 

The PHP Foundation’s account adds context: the earlier OOM concern remained unresolved amid difficult compatibility tradeoffs, limited specialist resources and an unclear exploitation path. Reports demonstrating concrete impact changed its priority. The Foundation also states that people remained responsible for security decisions and patch work. 

The operational implication is that **exploit complexity should not be treated as dependable protection**. This incident supports investing in fast runtime inventory, reproducible deployments and a tested isolation procedure. Those capabilities make an emergency patch actionable across a fleet.

## Conclusion

Pieter Levels’ shutdown illustrates the containment decision PHP2Shell forced on website operators. The durable lesson is to make runtime exposure and patch status verifiable.

**Inventory every PHP-serving deployment, apply the appropriate upstream or vendor fix, replace running workers and review earlier exposure.** For each production service, record the fixed package or image, its deployment time and a successful dynamic health check. Keep containment in place wherever that verification is incomplete.
