php2shell (CVE-2026-109618): patch PHP in Docker and Forge - Relaticle             [  Back to blog ](https://relaticle.com/blog) 

 ![php2shell: how we patched Relaticle, and how to patch yours](https://relaticle.com/storage/ink/01M5G5GEJGV9DTSAY9VT4EWPHY.png)

php2shell is the name for two critical PHP vulnerabilities, [CVE-2026-109618](https://github.com/php/php-src/security/advisories/GHSA-w8hw-w9fx-j79w) and [CVE-2026-109619](https://github.com/php/php-src/security/advisories/GHSA-6wmf-4rv5-p3rp). If you self-host Relaticle, update to v3.6.7 or later, which ships PHP 8.5.12, and confirm it with `php -v` inside the app container. Either flaw can let an attacker without an account run code on a server that answers web requests with PHP. PHP fixed both on 21 October 2026 in versions 8.5.12, 8.4.27, 8.3.36 and 8.2.35. Relaticle Cloud runs the patched PHP, and its customers do not need to do anything.

[](#what-php2shell-is "Permalink")What php2shell is
---------------------------------------------------

Both flaws are rated critical, with a CVSS v4.0 score of 9.2. The attacker needs no login, and their code runs as the account PHP serves requests under.

CVE-2026-109618 is remote code execution through out-of-memory corruption. If PHP runs out of memory while internal request data is only partly set up, the cleanup that follows can treat that data as valid. The advisory lists multipart upload tricks that push a request out of memory while it stays inside its apparent size limits.

CVE-2026-109619 is a use-after-free through stale global state. Some state owned by one request survives after its memory is freed. A later request handled by the same PHP worker can use that state before PHP resets it. Besides code execution, the advisory confirms memory disclosure.

[PHP's security advisory](https://www.php.net/archive/2026.php#2026-10-21-5) says every PHP installation that serves web requests is at risk: PHP-FPM, Apache with mod\_php, php-cgi, FrankenPHP and LiteSpeed. The PHP team rates the risk highest for mod\_php, where a demonstrated exploit runs before any application code.

PHP-FPM is not spared. The CVE-2026-109619 advisory validated an attack on a normal FPM pool through session upload progress. That path also needs a suitable operation in the application. Session upload progress is on by default, and the application never has to call `session_start()` for it to run.

PHP 8.1 and older get no official release. The PHP security team published minimal source backports for 7.4, 8.0 and 8.1, for people who build PHP themselves. Calif, one of the teams credited with the findings, dates the earliest affected code it found to PHP 5.4. If you run 8.2, the patch buys time but not much. PHP 8.2 reaches end of life on 31 December 2026 and gets no security fixes after that.

Linux distributions and LTS vendors received the patches in advance, according to PHP. That covers PHP installed from your operating system's packages. It does nothing for PHP built into an application image.

The release did not go to plan. The CVE identifiers circulated on Hacker News and social media on 20 October, before the coordinated date. PHP had planned the release for 22 October and moved it up a day. At 19:33 UTC that evening, it [announced a critical release](https://news-web.php.net/php.announce/509) for 14:00 UTC the next day. The advisories went public at 13:34 UTC on 21 October.

[Cloudflare reported](https://blog.cloudflare.com/php-vulnerabilities-waf-protection/) attack traffic against its customers, and attackers changing their payloads to slip past its new rules. [Tenable reports](https://www.tenable.com/blog/php2shell-cve-2026-109618-cve-2026-109619-frequently-asked-questions-about-critical-php-remote) that watchTowr reproduced both flaws and is seeing exploitation attempts. Code that claims to exploit php2shell is circulating publicly. The PHP Foundation said the leaked proofs of concept it inspected did not work at release time, and Tenable has not verified any of them. Do not run them.

On 21 October, [Reuters listed](https://www.globalbankingandfinance.com/factbox-websites-taken-offline-over-php-risks/) sites taken offline as a precaution. They included Germany's federal IT provider ITZBund, French prefecture sites, Finland's state IT centre and Dutch government sites. The Wikimedia Foundation took several systems down until they could be patched. The [UK NCSC](https://www.ncsc.gov.uk/news/critical-security-issue-affecting-php) urged organizations to update, and to consider taking offline any system they cannot fix straight away.

[](#three-things-that-leave-a-patched-server-running-old-php "Permalink")Three things that leave a patched server running old PHP
---------------------------------------------------------------------------------------------------------------------------------

php2shell lives in PHP itself. As Cloudflare notes, updating your code or plugins alone does not fix it. Updating Laravel or your Composer packages does not fix it either. The fix is a patched PHP binary that is actually running, and three things can stand between a server and that state.

**PHP in a container belongs to the image.** Running `apt upgrade` on the Docker host leaves the PHP inside your containers untouched. The image has to be rebuilt on a patched base, then pulled, then the containers recreated. Relaticle's `latest` tag only moves when we cut a release, so it carried PHP 8.5.11 until v3.6.7. Our base image, serversideup/php, [published patched builds](https://github.com/serversideup/docker-php/releases/tag/v5.0.2) at 17:31 UTC on 21 October.

**A managed server may not patch PHP for you.** [Laravel Forge's guidance](https://laravel.com/forge/docs/knowledge-base/php-security-release-october-2026) is direct: "Laravel Forge's automatic security updates do not patch PHP." Forge installs PHP from a separate package repository, and Ubuntu's unattended upgrades only cover Ubuntu's own security repository. The fix is the "Update PHP" action on the server's PHP tab. Forge says to run it for every installed version, including versions no site uses.

**Long-running PHP keeps the old binary in memory.** Horizon, queue workers, Reverb, Octane and a long-running scheduler hold the PHP they started with until they restart. Forge lists `php artisan horizon:terminate`, `php artisan queue:restart` and `php artisan octane:reload` for this. The advisories target PHP that answers web requests. Restart the rest anyway, so the version on disk and the version running agree.

[](#what-we-did-on-relaticle-cloud "Permalink")What we did on Relaticle Cloud
-----------------------------------------------------------------------------

Relaticle Cloud is hosted by Hetzner in Germany and managed through Laravel Forge.

| Time (UTC) | Event |
|---|---|
| 20 Oct, 19:33 | PHP announces a critical release for the next day |
| 21 Oct, 13:34 | PHP publishes the advisories and the patched releases |
| 21 Oct, 17:31 | serversideup/php publishes patched base images |
| 21 Oct, 21:03 | Relaticle Cloud runs PHP 8.5.12, with Horizon and Reverb restarted on it |
| 21 Oct, 21:42 | Relaticle v3.6.7 released, with images on PHP 8.5.12 |

Our update landed about seven and a half hours after the advisories went public. Most of that gap is the Forge lesson: nothing patched PHP until we ran the update ourselves. Our [security page](/security) lists who hosts Relaticle Cloud and what each provider can access.

[](#if-you-self-host-relaticle "Permalink")If you self-host Relaticle
---------------------------------------------------------------------

Relaticle's Docker image runs PHP-FPM behind nginx, and it leaves session upload progress on, as PHP does by default. Version 3.6.6 and earlier ship PHP 8.5.11 or older. Version 3.6.7 and later ship PHP 8.5.12 or newer.

Check what you are running:

```
docker compose exec app php -v

```

You want `PHP 8.5.12` or later. Anything older is exposed.

Take a backup first. Our [backup and upgrade runbook](/blog/backups-upgrades-and-security-for-a-self-hosted-crm) covers the database, uploaded files and secrets, and how to prove a restore works. Then pull the release and recreate the containers:

```
docker compose pull
docker compose up -d
docker compose exec app php -v

```

The default `compose.yml` runs four services from the same image: `app`, `horizon`, `scheduler` and `reverb`. `docker compose up -d` recreates all four, so every PHP process restarts on the new binary.

If you pinned a version, change the tag on all four services to `ghcr.io/relaticle/relaticle:3.6.7` or later before you pull. A `3.6` tag also follows patch releases. Docker Hub carries the same image as `manukminasyan/relaticle`. If you run PHP workers outside this Compose file, restart and check them too.

The [self-hosting guide](/docs/self-hosting) covers the full Docker setup. The [self-hosting overview](/blog/self-hosting-an-ai-native-crm-in-2026) explains what running Relaticle yourself involves.

[](#if-you-cannot-update-today "Permalink")If you cannot update today
---------------------------------------------------------------------

Updating is the only complete fix. If you need a day to test the new release first, the stopgap below blocks the two attack paths the advisories confirm. It does not cover every variant.

Relaticle does not use session upload progress, and fatal error backtraces only add detail to fatal error messages. Turning both off does not change how the CRM works. Create `php2shell.ini` next to your `compose.yml`:

```
session.upload_progress.enabled = 0
fatal_error_backtraces = 0

```

Add it to the `app` service's volumes in `compose.yml`, keeping the existing storage volume:

```
services:
  app:
    volumes:
      - storage:/var/www/html/storage/app
      - ./php2shell.ini:/usr/local/etc/php/conf.d/zzz-php2shell.ini:ro

```

Recreate the container and check both settings:

```
docker compose up -d --force-recreate app
docker compose exec app php -i | grep -E 'progress.enabled|backtraces'

```

Both lines should read `Off`. PHP-FPM reads the same configuration directory as the `php` command, so this check covers the web server too.

PHP's advisory also lists `memory_limit=-1` for CVE-2026-109618. That removes the memory limit an attacker can deliberately hit. It does not stop every allocation failure, and it lets a single request use all of the container's memory. Read the advisory's caveats before you reach for it.

Keep upload progress off after you update. The CVE-2026-109619 advisory suggests it if you do not need the feature, as more attackers look for flaws in this rarely used, rarely tested code. On a Relaticle install, the mount can stay.

For other PHP apps, the upload progress setting applies on every supported PHP version, and `fatal_error_backtraces` exists only on PHP 8.5. Set both in `php.ini` or the FPM pool, not with `ini_set()` or `.user.ini`, and restart every worker. The PHP advisory and the GHSAs for [CVE-2026-109618](https://github.com/php/php-src/security/advisories/GHSA-w8hw-w9fx-j79w) and [CVE-2026-109619](https://github.com/php/php-src/security/advisories/GHSA-6wmf-4rv5-p3rp) have the full detail.

If you find a security issue in Relaticle, email security@relaticle.com with what you found and the steps to reproduce it.

 Tagged: [ #self-hosting ](https://relaticle.com/blog/tag/self-hosting) [ #open-source ](https://relaticle.com/blog/tag/open-source) 

Related posts
-------------

 [  Engineering   Sep 22, 2026  

 Custom fields that work everywhere without per-field code 
-----------------------------------------------------------

How Relaticle makes custom fields available across forms, APIs, chat, and MCP, with shared normalization, clear empty-value semantics, and explicit limits.

 ![Custom fields that work everywhere without per-field code](https://relaticle.com/storage/ink/01M17KWS5WQE6WCDDCM1FXG3D1.png) ](https://relaticle.com/blog/custom-fields-that-work-everywhere-without-per-field-code) [  Engineering   Sep 11, 2026  

 Designing an MCP tool suite for a CRM: four lessons 
-----------------------------------------------------

What building Relaticle’s MCP server taught us about schemas, shared custom-field validation, authorization, and client discovery.

 ![Designing an MCP tool suite for a CRM: four lessons](https://relaticle.com/storage/ink/01M17KWKXTN38DSBQ83EP03CHQ.png) ](https://relaticle.com/blog/designing-an-mcp-tool-suite-for-a-crm) 

###    On this page
