Dev.to Security 🔐 Cybersecurity 👁 0 📖 5 min read

PHP2Shell: Two Critical Remote Code Execution Flaws in PHP

27 October 2026 | CVE-2026-109618 and CVE-2026-109619 | CVSS v4.0: 9.2 each What happened? On 21 October 2026 the PHP project published a security advisory for two critical memory-safety vulnerabilities in PH

27 October 2026 | CVE-2026-109618 and CVE-2026-109619 | CVSS v4.0: 9.2 each

What happened?

On 21 October 2026 the PHP project published a security advisory for two critical
memory-safety vulnerabilities in PHP itself; the patched releases carry a ChangeLog date
of 22 October 2026. Known as PHP2Shell, these bugs can under certain conditions enable
unauthenticated remote code execution (RCE). This is not a WordPress plugin or
Composer dependency bug: even well-written application code can run on a vulnerable PHP
runtime.

One note on the name: "PHP2Shell" does not appear in the advisories published by the PHP
project, CERT-EU or the NCSC. It spread through security vendors and the NCSC-NL inventory
repository; the official documents refer to the flaws by their CVE and GHSA identifiers.

Affected versions

Branch Affected First fixed
8.5 < 8.5.12 8.5.12
8.4 < 8.4.27 8.4.27
8.3 < 8.3.36 8.3.36
8.2 < 8.2.35 8.2.35
8.1 and older all official source backports (7.4 / 8.0 / 8.1)

That last row is the one most often skipped. The flaw does not concern only the
supported branches: Google Cloud's analysis gives the affected range as "all versions of
PHP from 5.4 through 8.5.11", and the NCSC states that "organisations using any version of
PHP are affected". PHP 8.1 and older no longer receive regular updates, but they are not
out of scope
— the PHP security team published source backports for 7.4, 8.0 and 8.1
(branches named in the form PHP-8.1-CVE-2026-109618-109619). If you are stuck on an old
release there is something to do; do not wave it away as unsupported.

php -v
systemctl list-units --type=service --all 'php*-fpm.service'
docker ps --format '{{.Names}} {{.Image}}'

Linux vendors sometimes backport security fixes without changing the apparent upstream
version, so verify vendor security advisories in addition to php -v. PHP 8.2 reaches
upstream end of life on 31 December 2026.

Root causes

CVE-2026-109618 (out-of-memory corruption): While parsing HTTP forms or uploads, PHP
may abort processing when it reaches memory_limit. Cleanup can run against partially
initialized internal structures, resulting in memory corruption.

CVE-2026-109619 (stale global state): References to request-owned data can survive
after the underlying memory is freed. A later request on the same worker can access those
stale references, creating a use-after-free condition.

And there is a third one. CERT-EU's advisory 2026-018 also lists CVE-2026-115560.
Its technical details have not been published yet, and the recommended measure is
"set session.upload_progress.enabled=0 and restart every worker until the next regular
bugfix release" — meaning this third issue is not closed by the releases above. Keep
watching PHP security announcements after you have patched.

How exploitation works

Conceptually, an attacker (1) reaches a PHP-served HTTP endpoint, (2) supplies specially
structured data that reaches vulnerable native request-parsing or error paths,
(3) triggers invalid memory state, and (4) may achieve code execution under PHP worker
privileges. This is a mechanism overview, not a weaponized exploit. Exploitability is
configuration-dependent, not guaranteed on every server. Assess PHP-FPM, Apache
mod_php, php-cgi, FrankenPHP and LiteSpeed; CERT-EU reports that the PHP team
considers mod_php the highest-risk setup.

How to identify exposure

The commands above provide an initial inventory. CLI PHP and the actual web-serving
PHP-FPM runtime may differ.
Inspect FPM services, container images, hosting panels and
distribution backports separately. Do not expose phpinfo() to the internet.

How to fix it

1. Patch: Upgrade to PHP 8.5.12 / 8.4.27 / 8.3.36 / 8.2.35 or newer patched releases.
On Debian/Ubuntu, review sudo apt update and sudo apt upgrade; on RHEL-family systems,
consider sudo dnf update --security. These can change packages beyond PHP, so plan and
test production changes. If you are on 7.4 / 8.0 / 8.1, apply either your distribution's
backport or the source backport published by the PHP team.

2. Replace workers: Restart the matching FPM service, for example
sudo systemctl restart php8.4-fpm; restart Apache when using mod_php. For
Docker/Kubernetes, deploy newly built containers/pods from patched images. Restarting
a container based on an old image does not patch it. Use rolling updates when redundant
replicas are available. Upgrading packages on disk leaves the old libphp.so or
php-fpm binary resident in running worker processes — the replacement step is not
optional.

3. Verify: Confirm the effective web-serving runtime and vendor patch status, new
worker processes, application health, login/upload flows and logs. Ensure no stale workers
or images remain.

Temporary controls if patching is delayed

These do not fully mitigate the vulnerabilities. In the advisory's own words, such
measures reduce exposure to specific attack paths but do not make an installation safe:

  • Set memory_limit=-1 and lower post_max_size (for example 8M if uploads are unnecessary, 32M if they are). Counterintuitively, lowering memory_limit does not help — the trigger is precisely hitting the memory ceiling and aborting mid-request.
  • Do not constrain process memory with RLIMIT_AS or RLIMIT_DATA.
  • Set session.upload_progress.enabled=0 in php.ini, an FPM pool or server configuration and restart every worker. The advisory explicitly says not to rely on ini_set() or FPM .user.ini for this.
  • On PHP 8.5, consider fatal_error_backtraces=0 and restart the workers.

Alongside these, run PHP workers as unprivileged users, minimize writable paths and
outbound network access, and maintain WAF controls. Consider isolating exposed services
that cannot be patched. WAF rules and disable_functions do not repair a memory flaw.

What should defenders investigate?

Look for unexplained PHP-FPM/Apache crashes or OOM errors, unusual multipart POST
requests, shell processes spawned by PHP workers (sh, bash, curl, wget, nc),
unexpected file modifications, abnormally long PHPSESSID cookies and anomalous outbound
connections. None alone proves exploitation.

If you do suspect something, mind the order: capture a memory image before restarting.
Google Cloud's guidance is explicit here — restarting workers permanently destroys
volatile heap evidence. Patching the host is urgent, but if you restart without taking a
forensic copy you will never learn what happened. Preserve evidence, isolate suspected
hosts, and assess credential rotation. Installing the patch does not remove a
pre-existing compromise.

Windows build note (26 October)

Rebuilt official Windows packages 8.5.12-1, 8.4.27-1, 8.3.36-1 and 8.2.35-1 also
address CVE-2026-111497 in the bundled Brotli library. This is a separate issue from
the two PHP2Shell CVEs.

There is a trap here: because the PHP runtime itself is unchanged, php -v prints the
same version string before and after this update. The detection command at the top of
this article quietly fails in exactly this case; on Windows you need to check the package
build suffix (-1) or file hashes instead.

Conclusion

PHP2Shell demonstrates that secure application code cannot compensate for an unsafe
runtime. Follow inventory → patch → worker/container replacement → validation →
incident review
. Do not start the inventory at 8.2: the affected range reaches down to
5.4, and official backports exist for the older branches too. The PHP project says there
are no complete temporary mitigations; upgrading is the definitive fix.

Official Sources

📰 Read the original article on Dev.to Security

Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.