Security guide

PHP2Shell (CVE-2026-109618, CVE-2026-109619): what it is, how to patch, and what it means for your team

Two unauthenticated remote code execution flaws in PHP itself, found with AI-assisted research. Here's how to check whether your hosts are exposed, which fixed packages to install, and how to get ready for the next one.

October 23, 2026

PHP2Shell is the name given to two flaws in the PHP runtime, CVE-2026-109618 and CVE-2026-109619, that let an unauthenticated attacker run code on a server by sending it a crafted request. Both are rated 9.2 under CVSS v4.0. The PHP project released fixed versions on October 21, 2026, a day earlier than planned, after the CVE identifiers leaked online. CIQ shipped fixed packages for Rocky Linux from CIQ Pro (RLC Pro) LTS 9.6 and 9.2 about three and a half hours after the upstream fix went public, then fixes for RLC Pro 8, 9, and 10, RLC Pro LTS 8.6, and CIQ Bridge over the next two days. Nathan Blackham, who leads the CIQ engineers who shipped those fixes, wrote about the response the day it happened.

This guide covers what the bugs are, how to find out whether your hosts run an affected PHP, how to install the fixed packages on each RLC Pro release, what to do while you patch, and what this event says about the next one. The CIQ knowledge base article carries the live patch table and is the place to check current status; the table on this page says when it was last updated.

What PHP2Shell is and why application code doesn't protect you

The two CVEs are separate bugs in the same part of PHP: the code that sets up and tears down a request.

  • CVE-2026-109618 is a memory corruption bug triggered when PHP runs out of memory while parsing a multipart form body (the RFC 1867 upload path). If the out-of-memory condition interrupts PHP while its internal request data is only partly initialized, the cleanup that follows treats that invalid data as valid.
  • CVE-2026-109619 is a stale state bug. Request-owned internal state can survive after its backing memory is freed, and a later request handled by the same worker can use it before normal initialization resets it. The PHP advisory also lists memory disclosure as a confirmed impact.

On Apache with mod_php, an unauthenticated request can trigger CVE-2026-109618 before any application code runs, and full remote code execution was demonstrated with default settings. There, a well-written framework, strict input validation, and firewall rules for your own endpoints don't help, because the vulnerable code runs while PHP is still reading the request. On PHP-FPM, exposure depends on the application's code paths. FrankenPHP and LiteSpeed are considered likely susceptible but haven't been fully validated. Patch every setup regardless. Command-line-only installations are affected but lower priority unless an attacker can control input to the CLI.

Researcher Ryan A at the security firm Calif reported the first flaw on August 11 while auditing PHP through OpenAI's Patch the Planet program. OpenAI reported the same root cause independently, and Wiz Research followed with more attack paths. One of the two bugs was already known: a PHP core developer found the out-of-memory handling problem in a 2024 audit, and it sat unfixed because nobody had shown a path to code execution and the team could not agree on a fix. Two years later, AI-assisted research found that path. The affected range is PHP 5.4 through 8.5, which is every PHP release since 2012. The PHP project says there are no complete mitigations and that updating is the only safe choice.

Check your PHP version and module stream

Start by finding out what you run. On any host:

php -v
rpm -q php php-fpm php-cli
systemctl is-active php-fpm httpd

A fixed build reports PHP 8.2.35, 8.3.36, 8.4.27, or 8.5.12 upstream, or one of the distribution builds in the table below. The distribution version string is what matters on RLC Pro, because the fix for the 8.0 stream shipped as a patched 8.0.30, not a new upstream release.

On Enterprise Linux 8 and 9, PHP is delivered as AppStream module streams, so the version number alone doesn't tell you which stream you're on or whether a fix exists for it:

dnf module list php
dnf module list --enabled php

The stream marked [e] is enabled, and [d] marks the default. On Enterprise Linux 9, the base php package is 8.0 and php:8.1 and php:8.2 are optional streams. On Enterprise Linux 8, the default stream is php:7.2, with php:7.3, php:7.4, and php:8.0 as alternatives and php:8.2 added later.

To check every host at once, run the same commands through your automation platform. A job template, such as one in Ascender Pro, that collects php -v and dnf module list --enabled php into a report gives you the inventory the rest of this guide assumes.

The EL8 default stream: 7.2 gets no fix

This is the trap on Enterprise Linux 8. If someone ran dnf install php without enabling a stream, the host has PHP 7.2. PHP 7.2 reached end of life upstream in November 2020, there is no upstream fix branch for it, and the CIQ knowledge base is explicit: PHP 7.2 and 7.3 have no fix branch and are unmitigated at the source level. The php:8.0 stream on EL8 also has no patched build. On RLC Pro 8 and RLC Pro LTS 8.6, the fixed streams are php:7.4 and php:8.2.

Switch streams now. The 7.4 stream is the smallest jump from 7.2. The 8.2 stream is the better long-term choice, because PHP 8.2 still receives upstream releases. Test on one host first:

sudo dnf module reset php
sudo dnf module enable php:8.2
sudo dnf distro-sync php\*
sudo systemctl restart php-fpm

Use php:7.4 in place of php:8.2 if your application isn't ready for PHP 8. After the switch, run your application's smoke tests. PHP 8 removed some deprecated behavior from 7.x, so a code base that was last touched on 7.2 may need small fixes. That work is still smaller than running an unpatched remote code execution flaw on the public internet.

Install the fixed packages, by RLC Pro release

On every RLC Pro release with a fixed build, the fix arrives through the normal update path. Run the update, then restart every PHP worker, because the running processes keep the old code in memory until they restart:

sudo dnf update php\*
sudo systemctl restart php-fpm        # PHP-FPM
sudo systemctl restart httpd          # Apache with mod_php

If the update doesn't appear, make sure the host is subscribed to the right channel with Depot Client, for example sudo depot enable lts-9.6, sudo depot enable rlc-pro-9, or sudo depot enable rlc-pro-10, then run the update again. On CIQ Bridge hosts the command is sudo yum update php\* followed by the same restarts.

Confirm the result with rpm -q php and check that it matches the fixed version for your stream in the table below.

Patch timeline

The table shows the fixes CIQ has published as of October 26, 2026, taken from the knowledge base article. The knowledge base is updated as Engineering ships; this page is updated from it before each change goes live.

Product and stream Status Fixed package As of
RLC Pro LTS 9.6, base PHP 8.0 Fixed php-8.0.30-3.4.el9_6_ciq October 21, 2026
RLC Pro LTS 9.2, base PHP 8.0 Fixed php-8.0.30-1.2.el9_2_ciq October 21, 2026
RLC Pro LTS 9.2, php:8.2 Fixed php-8.2.35-1 October 26, 2026
RLC Pro LTS 9.2, php:8.3 Fixed php-8.3.36-1 October 26, 2026
RLC Pro 9, base PHP 8.0 Fixed php-8.0.30-8.el9_8.1 October 22, 2026
RLC Pro 10, PHP 8.3 Fixed php-8.3.36-1.el10_2 October 22, 2026
RLC Pro 8, php:7.4 and php:8.2 Fixed php-7.4.33-8 and php-8.2.35 October 22, 2026
RLC Pro LTS 8.6, php:7.4 and php:8.2 Fixed php-7.4.33-8 and php-8.2.35 October 23, 2026
CIQ Bridge, CentOS 7.9, PHP 5.4 Fixed php-5.4.45-1.2.el7_9.ciqcbr October 23, 2026
EL8 php:7.2, php:7.3, and php:8.0 streams No fix available Switch to php:7.4 or php:8.2 October 26, 2026

The RLC Pro LTS 9.6 and 9.2 packages went out on October 21, about three and a half hours after the upstream fix was published. That's what a long-term support release is for: the version stays pinned, the security work continues, and a fix ships to everyone on that version without a version upgrade.

Community Rocky Linux users should check the project's own errata: RLSA-2026:87151 for Rocky Linux 9, RLSA-2026:87070 for Rocky Linux 10, and RLSA-2026:87073 and RLSA-2026:87080 for the php:8.2 and php:7.4 streams on Rocky Linux 8. If dnf update php\* finds nothing, check the installed package version directly with rpm -q php.

Interim steps while you patch

If a host can't be patched today, reduce its exposure. These settings come from the PHP advisory and the CIQ knowledge base article. They must be set in php.ini, an FPM pool file, or the web server configuration, because ini_set() and .user.ini apply too late to matter, and every PHP worker has to restart afterwards.

For CVE-2026-109618, remove the out-of-memory trigger from the upload path. In php.ini:

memory_limit = -1
post_max_size = 8M        ; 32M if your application needs file uploads
; keep upload_max_filesize below post_max_size

Because memory_limit = -1 removes PHP's own memory ceiling, give the process a ceiling from outside with a container or cgroup memory limit. Do not use RLIMIT_AS or RLIMIT_DATA for this, since those reintroduce the same failure mode.

For CVE-2026-109619, turn off the features that carry state between requests. In php.ini:

session.upload_progress.enabled = 0
fatal_error_backtraces = 0    ; PHP 8.5 only

An FPM pool file such as /etc/php-fpm.d/www.conf rejects those lines, and php-fpm will not start. In a pool file, set the same values with php_admin_value and php_admin_flag, which also stop applications from overriding them:

php_admin_value[memory_limit] = -1
php_admin_value[post_max_size] = 8M        ; 32M if your application needs file uploads
php_admin_flag[session.upload_progress.enabled] = off
php_admin_flag[fatal_error_backtraces] = off    ; PHP 8.5 only

Run sudo php-fpm -t to check the configuration before you restart.

Three further options, each with a cost:

  • Set pm.max_requests = 1 in the FPM pool so no worker handles a second request. It closes the stale state path at a significant performance cost.
  • Block multipart/form-data requests at the reverse proxy. The knowledge base article has an nginx example; do not limit the rule to POST. This breaks file uploads and addresses only the first CVE.
  • Stop and disable php-fpm on hosts that don't need it, and comment out the PHP LoadModule line on Apache hosts that only serve static content.

Verify with systemctl is-active php-fpm and a grep across /etc/php.ini, /etc/php.d/, and /etc/php-fpm.d/. Then patch anyway. The PHP project's own words are that these measures reduce exposure to specific attack paths but do not make an installation safe. One setting outlives the patch: on October 23, PHP asked everyone to keep session.upload_progress.enabled = 0 until its next regular bugfix release, which will carry a full advisory for a related, unlikely RCE path, CVE-2026-115560. Applications that never switch session.serialize_handler at runtime can turn the feature back on.

Containers: rebuild images on a fixed base

A container image is a snapshot. Patching the host does nothing for the PHP inside the image, and dnf update inside a running container is lost at the next restart. Treat PHP2Shell as a rebuild event:

  1. Find every image that contains PHP. If your registry scans images, filter on the two CVE identifiers. If not, docker run --rm <image> php -v across your image list works.
  2. Move the base image to a fixed tag. For the official php images that is 8.2.35, 8.3.36, 8.4.27, or 8.5.12 and later. For images built on Rocky Linux, pull the current rockylinux base and install PHP from the fixed stream so the package version matches the table above.
  3. Rebuild, run tests, push, and redeploy. Restarting a pod on the old image changes nothing.
  4. Add a memory limit to the pod or container specification if one is missing. It's the recommended way to apply the memory_limit = -1 mitigation, and it remains good practice after patching.

Third-party software that bundles its own PHP, including appliances and control panels, needs the vendor's update. The Dutch NCSC maintains a public inventory of vendor statements that is worth checking against your software list.

What PHP2Shell means for the next CVE

PHP2Shell is part of a pattern. Two things about it are likely to repeat.

Old bugs are new again. The out-of-memory bug was found in 2024 and left alone because exploiting it looked impractical. AI-assisted research changed the economics of proving a bug exploitable. The Google Threat Intelligence Group reported on September 30, 2026 that monthly vulnerability disclosures doubled between January and August of this year, from 5,045 to 10,740, and that half of the vulnerabilities it identified as likely AI-discovered result in remote code execution, against 26 percent across the wider CVE ecosystem. Every mature code base has a backlog of findings someone decided were too hard to exploit. Expect more of them to resurface with working exploits attached.

Exploitation follows the fix quickly. watchTowr observed exploitation attempts in its honeypots on October 21, the day the fix was released. GTIG suggests attackers are using AI tools to compare patches and versions and turn known vulnerabilities into working exploits faster. The time it takes your distribution to ship a tested build is part of your exposure.

Versions upstream abandoned are still in production. PHP 7.4, 8.0, and 8.1 got source patches but no binaries. PHP 7.3 and older got nothing. The PHP 8.0 that ships as the base package on Enterprise Linux 9 is itself end of life upstream, which is why distribution engineers, not the PHP project, produced the fixed 8.0.30 builds. No upstream branch covers PHP 5.4, so CIQ engineers backported the fix for CIQ Bridge, CVE remediation for CentOS 7.9 while you migrate. Whoever maintains the versions you run is your security team for those versions.

The practical response is unglamorous. Keep an inventory that knows which stream every host runs. Pin production to a long-term support release so a fix arrives as a package update rather than a version migration. Have engineers who read upstream patches and backport them as their daily job, in-house or through a partner. Rebuild containers on a schedule, not only in emergencies. And measure your own time from upstream release to patched fleet, because that number is what the next PHP2Shell will test. Our companion guide, how to stay secure when AI finds vulnerabilities faster, goes through each of those steps.

FAQs

What is PHP2Shell?

PHP2Shell is the name given to two remote code execution flaws in the PHP runtime, CVE-2026-109618 and CVE-2026-109619, both rated 9.2 under CVSS v4.0. An attacker doesn't need to log in. Because the flaws are in PHP itself, applications built on it inherit the exposure, and every PHP version back to 5.4 is affected.

Which upstream PHP versions fix PHP2Shell?

PHP 8.2.35, 8.3.36, 8.4.27, and 8.5.12, released by the PHP project on October 21, 2026. The PHP security team also published source patches for 7.4, 8.0, and 8.1 but no binaries, because those branches are end of life. PHP 7.3 and older, including PHP 5, have no upstream fix at all.

Is RLC Pro patched for PHP2Shell?

Yes, for the streams in the patch timeline above. RLC Pro LTS 9.6 and RLC Pro LTS 9.2 base PHP packages shipped on October 21, 2026, about three and a half hours after the upstream fix went public. RLC Pro 8, 9, and 10 followed on October 22, RLC Pro LTS 8.6 and CIQ Bridge on October 23, and the php:8.2 and php:8.3 streams on RLC Pro LTS 9.2 on October 26. The knowledge base article carries the current table.

I'm on EL8 and ran dnf install php. Am I covered?

Probably not. On Enterprise Linux 8, that command installs the php:7.2 module stream unless you've enabled another stream, and the 7.2 stream gets no fix from anyone because PHP 7.2 has no upstream fix branch. Run dnf module list php to see which stream is enabled, then switch to php:7.4 or php:8.2, which both have fixed builds.

Is community Rocky Linux patched for PHP2Shell?

The Rocky Linux project publishes its own errata. Fixed packages are listed under RLSA-2026:87151 for Rocky Linux 9, RLSA-2026:87070 for Rocky Linux 10, and RLSA-2026:87073 and RLSA-2026:87080 for the php:8.2 and php:7.4 streams on Rocky Linux 8. CIQ doesn't publish packages for community Rocky Linux; check errata.rockylinux.org for status.

I run CentOS 7. Is there a fix for PHP2Shell?

CIQ Bridge customers have a backported fix for PHP 5.4, shipped as php-5.4.45-1.2.el7_9.ciqcbr on October 23, 2026. No upstream branch covers PHP 5.4, so CIQ engineers backported the fix themselves. CIQ Bridge is CVE remediation for CentOS 7.9 while you migrate to RLC Pro or RLC Pro Hardened.

How do we get security updates out faster?

Speed comes from engineers who read the upstream patch, backport it into the versions you run, build and validate it, and publish it as their daily work. For PHP2Shell, CIQ shipped RLC Pro LTS 9.6 and 9.2 fixes about three and a half hours after the upstream release. Pair that with an inventory that tells you which hosts run which PHP stream, and a rollout tool that can restart PHP workers everywhere.

What is the effect of AI now finding vulnerabilities so easily?

Bugs once parked as too hard to exploit are now candidates for remote code execution. The Google Threat Intelligence Group reported that monthly CVE disclosures doubled between January and August 2026, and that half of the vulnerabilities it identified as likely AI-discovered result in remote code execution, against about a quarter across the wider CVE ecosystem. PHP2Shell turned a memory bug a PHP core developer found in a 2024 audit into a working exploit, with help from frontier AI models.

How do organizations stay secure as CVEs arrive faster?

Patch quickly on the versions you run, know which streams you're on, rebuild container images on fixed bases, and have engineers who handle CVE triage and backports every day, whether your own or a partner such as CIQ. Treat mitigations as a stopgap until you patch.

Sources

Need help getting PHP2Shell patched across your estate, or want CIQ engineers handling the next CVE?

Talk to an engineer

Built for scale. Chosen by the world’s best.

2.75M+

Rocky Linux instances

Being used world wide

90%

Of fortune 100 companies

Use CIQ supported technologies

250k

Avg. monthly downloads

Rocky Linux

9

Enterprise products

Spanning the kernel to the orchestrator