> ## Documentation Index
> Fetch the complete documentation index at: https://blog.onetsolutions.net/llms.txt
> Use this file to discover all available pages before exploring further.

# php2shell (CVE-2026-109618 and CVE-2026-109619): Two Unauthenticated RCEs in PHP Itself

> Two unauthenticated remote code execution flaws in the PHP core, fixed on October 21. Who is affected, how to update, and what we did on our side.

*Published on October 21, 2026*

> [!WARNING]
>
> **CVE-2026-109618 and CVE-2026-109619, CVSS v4.0 9.2 each.** Two unauthenticated remote code execution flaws in the PHP core, whatever the application. The details leaked before the embargo ended and attacks have been seen since the morning of October 21. Fixed in **PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35**, released on October 21. Update now.

## The problem in two sentences

An unauthenticated HTTP request can corrupt PHP's internal state and lead to code execution, before the application even starts. WordPress, Magento, PrestaShop or an in-house app: every site served by PHP is in scope, patched or not.

According to the PHP security team, every installation serving web requests is affected: PHP-FPM, Apache with mod\_php, php-cgi, FrankenPHP and LiteSpeed. The risk is rated highest for **mod\_php**, where a working exploit has been demonstrated.

| CVE | Name | Mechanism |
| - | - | - |
| CVE-2026-109618 | RCE via OOM corruption | Out-of-memory handling interrupts PHP while internal request data is only partially initialised; request cleanup then treats that data as valid |
| CVE-2026-109619 | RCE via stale global state | Request-owned internal state outlives the memory behind it; the next request handled by the same worker can use it before it is reset |

The full technical details are in advisories [GHSA-w8hw-w9fx-j79w](https://github.com/php/php-src/security/advisories/GHSA-w8hw-w9fx-j79w) and [GHSA-6wmf-4rv5-p3rp](https://github.com/php/php-src/security/advisories/GHSA-6wmf-4rv5-p3rp).

## Timeline

| Date (UTC) | Event |
| - | - |
| October 20 | Both flaws leak ahead of a coordinated disclosure planned for October 22. PHP announces a security release for the next day |
| October 21, 07:43 | First attacks observed; the major providers roll out emergency WAF rules |
| October 21, afternoon | PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35 ship, ahead of the announced 14:00 slot |

The public fix now tells attackers where to look: expect attacks to ramp up against servers that are not yet updated.

## What we did at OnetSolutions

**Mitigation in place before the fix.** On October 21, before the fixed releases shipped, we disabled `session.upload_progress` on all our web hosting servers, for every PHP version on offer (7.0 to 8.4). We checked the effective values version by version.

**Fix installed the same day.** Our teams were on it from the moment the flaws leaked and followed the situation throughout. The fixed PHP releases went onto all our web hosting the same day they were published, for every version on offer, including PHP 7.0 to 8.1, which get a backported fix. The mitigation stays in place on top.

**Monitoring.** Real-time malware scanning stays on across our web hosting servers.

> [!NOTE]
>
> The mitigation narrows the attack surface; it does not close it. The PHP team is clear: only updating fixes these flaws.

## Assess your exposure

| Profile | Exposure | Action |
| - | - | - |
| OnetSolutions web hosting, PHP 8.2 or later | Handled by us | Nothing to do |
| OnetSolutions web hosting, PHP 7.0 to 8.1 | Handled by us, backported fix | Nothing urgent; [switching to PHP 8.2 or later](https://help.onetsolutions.net/web-hosting/php-version) is still recommended |
| VPS serving PHP to the internet | **Critical** | Update now, mitigate while you wait for the package |
| VPS running Apache with mod\_php | **Critical**, exploit demonstrated | Update first, before anything else |
| Site behind a CDN or WAF, origin reachable directly | **Critical** | The WAF can be bypassed: restrict the origin to the proxy's addresses |
| VPS without PHP | None | Nothing to do |

> [!NOTE]
>
> You run your VPS, so installing the fix there is up to you. The commands follow.

## Update PHP

Linux distributions received the patches in advance, so their packages follow within hours of the release.

```bash theme={null}
# Debian, Ubuntu
apt update && apt install --only-upgrade 'php*'

# RHEL, AlmaLinux, Rocky Linux
dnf upgrade 'php*'
```

Then restart every PHP process: one of the two flaws lives in the state a worker keeps from one request to the next.

```bash theme={null}
# Debian, Ubuntu
systemctl restart 'php*-fpm.service'
systemctl restart apache2 2>/dev/null

# RHEL, AlmaLinux, Rocky Linux
systemctl restart php-fpm
systemctl restart httpd 2>/dev/null

# Check the version being served
php -v
```

> [!WARNING]
>
> If you use the Remi repository (`rpms.remirepo.net`), it will not ship updates on October 21. The PHP team recommends switching to your distribution's packages or building from source.

**PHP 8.1 and earlier.** The PHP project no longer ships releases for these branches. Given the severity, its security team still published minimal fixes for [PHP 7.4](https://github.com/php/php-src/tree/PHP-7.4-CVE-2026-109618-109619), [8.0](https://github.com/php/php-src/tree/PHP-8.0-CVE-2026-109618-109619) and [8.1](https://github.com/php/php-src/tree/PHP-8.1-CVE-2026-109618-109619), to build yourself. Some distributions and extended-support vendors carry them in their packages: ask your vendor, or move to a supported version.

## If you cannot update right away

The PHP team lists measures that close some of the known attack paths. It warns that they do not make an installation safe.

### Against CVE-2026-109619 (stale global state)

Disable upload progress tracking in `php.ini` or a `conf.d` file loaded at startup, then restart every worker. `ini_set()` or a `.user.ini` is not enough: the setting has to apply before the request is parsed.

```bash theme={null}
# Debian, Ubuntu: one file for every version and every SAPI
for dir in /etc/php/*/*/conf.d; do
  printf 'session.upload_progress.enabled = 0\n' > "$dir/zz-php2shell.ini"
done
systemctl restart 'php*-fpm.service'
systemctl restart apache2 2>/dev/null
```

```bash theme={null}
# RHEL, AlmaLinux, Rocky Linux
printf 'session.upload_progress.enabled = 0\n' > /etc/php.d/zz-php2shell.ini
systemctl restart php-fpm
systemctl restart httpd 2>/dev/null
```

To enforce it in a specific PHP-FPM pool, add this to the pool's configuration (for example `/etc/php/8.3/fpm/pool.d/www.conf`):

```ini theme={null}
php_admin_flag[session.upload_progress.enabled] = off
```

On PHP 8.5, also set `fatal_error_backtraces = 0`: it closes the confirmed attack path through fatal error backtraces.

### Against CVE-2026-109618 (out of memory)

Lower the maximum request size: `post_max_size = 8M` if the application takes no file uploads, `32M` if it does, with `upload_max_filesize` below `post_max_size`.

The PHP team also suggests `memory_limit = -1`, provided a container or cgroup memory limit protects the server. Without that limit a single worker can eat all of the machine's memory, so do not apply it lightly.

### Check

```bash theme={null}
# PHP on the command line
php -i | grep -E 'session\.upload_progress\.enabled|post_max_size'

# PHP-FPM (adjust the version: php-fpm8.3 on Debian and Ubuntu, php-fpm on RHEL)
php-fpm8.3 -i | grep -E 'session\.upload_progress\.enabled|post_max_size'
```

Expected: `session.upload_progress.enabled => Off`.

## Look for traces

Attacks came before the fix. On a server that ran a vulnerable version, look for PHP files created or modified since October 20:

```bash theme={null}
# PHP files modified since October 20, newest first
find /var/www -type f -name '*.php' -newermt '2026-10-20' -printf '%TY-%Tm-%Td %TH:%TM %p\n' | sort -r | head -50
```

A file you did not deploy, especially in an upload directory, means a compromise. Treat the server as compromised: restore from a backup taken before October 20 and rotate every secret it holds.

## What next?

The mitigation can stay after the update: few applications use upload progress tracking.

The real issue lies elsewhere. PHP 8.1 and earlier no longer get official releases, and PHP 8.2 reaches end of life on December 31, 2026. If one of your sites still depends on them, now is the time to migrate. Any question? [Our team is available](https://help.onetsolutions.net/console/support) from your customer area.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.