PHP2Shell: Critical Unauthenticated RCE in PHP — Patch Now (CVE-2026-109618 & 109619)

This article is for learning and defence. Use what you read here only on systems you own or are explicitly authorised to test. Attempting to exploit these flaws on systems you do not control is illegal under India's IT Act and similar laws worldwide. Do not try to reproduce or weaponise these vulnerabilities.

  • Two critical PHP bugs, nicknamed php2shell, can lead to unauthenticated remote code execution on web-facing PHP.
  • Patch to 8.5.12, 8.4.27, 8.3.36 or 8.2.35 as soon as you can.
  • If you cannot patch an internet-facing host, take it offline until you can.
  • This post explains impact and patching only — not how to attack anyone.

If you run PHP on the public internet — WordPress, Laravel, custom APIs, shared hosting, the works — you need to read this today. In late October 2026 the security community lit up around a pair of critical PHP flaws that people are calling php2shell. CISA told operators to patch immediately. CERT-EU noted that proof-of-concept material was already circulating. That combination is why this is in the talks, and why Hackup's is covering it as a defence post, not a how-to.

Bottom line up front: update PHP, prioritise anything that faces the internet, and treat unpatched EOL versions as an emergency. Details below.

What happened

On 21 October 2026, CISA published an alert on critical vulnerabilities in PHP that require immediate patching. The PHP project and The PHP Foundation shipped security releases the same day. Two related issues (tracked as GHSA-w8hw-w9fx-j79w / CVE-2026-109618 and GHSA-6wmf-4rv5-p3rp / CVE-2026-109619) can lead to unauthenticated remote code execution with a CVSS score around 9.2.

As of the CISA alert at publication, exploitation in the wild had not been observed — but CERT-EU reported that PoCs were circulating, so the window to patch before opportunistic abuse is short. Urgency first; curiosity second.

Patch the runtime. Everything else — WAFs, monitoring, config tweaks — is a bridge until the fixed PHP is live.

The two CVEs, at a high level

I am deliberately staying conceptual. The goal is so you understand why the patch matters, not so anyone can recreate an attack.

CVE-2026-109618 — OOM / memory_limit and partial state

When PHP hits a memory limit or similar out-of-memory condition, it can interrupt work mid-flight. In the buggy versions, that interrupt path could leave behind partially initialised data. On a long-lived worker that goes on to serve more requests, that incomplete state becomes a serious problem: the process is no longer in the clean condition the engine assumes. Conceptually, that is how a memory-limit edge case escalates into remote code execution.

CVE-2026-109619 — stale global state after fatal / error handling

The sibling issue is about stale global state after fatal errors or aggressive error handling. PHP workers (especially under FPM, mod_php, and similar) reuse a process across many requests. If error handling leaves globals or other engine state "dirty" instead of fully resetting them, a later request on the same worker can interact with that leftover state in unsafe ways — including use-after-free style failures that, again at a conceptual level, open the door to RCE.

These are engine-level bugs in PHP itself, not a bug in your Laravel or WordPress code. Updating your app without updating the PHP binary does not close them. Conversely, patched PHP protects every app on that runtime.

Related: session upload progress (CVE-2026-115560)

There is also a related informational issue around session upload progress. Until your next PHP release cycle is fully applied, a simple temporary hardening step many operators are taking is:

session.upload_progress.enabled = 0

That setting is uncommon in many stacks, so disabling it is usually low-risk while you finish patching. Confirm against your own app's needs.

Who is at risk

Anything that serves PHP to the web is in scope. Risk is highest where the SAPI keeps workers alive and shares them across requests:

  • mod_php (often called out as highest risk)
  • PHP-FPM
  • php-cgi
  • FrankenPHP
  • LiteSpeed with PHP

Shared hosting, agency WordPress fleets, SaaS APIs, college and SME servers in India, cloud VMs with leftover PHP 8.1 images — if HTTP can reach PHP, treat it as exposed until you verify the version.

Fixed releases from the PHP project:

  • PHP 8.5.12
  • PHP 8.4.27
  • PHP 8.3.36
  • PHP 8.2.35

For PHP 8.1 and older, the PHP project itself is not shipping full supported releases the same way. You need vendor or LTS backports, or — better — an upgrade onto a fixed supported branch. The project did publish minimal source backports aimed at 7.4 / 8.0 / 8.1 for vendors who still maintain those lines. If your host is stuck on EOL PHP with no backport, that host should not stay on the public internet.

What to do now

  1. Inventory every place PHP runs. App servers, containers, shared hosts, CI images that somehow serve traffic, staging that is accidentally public. Write down the SAPI (FPM, mod_php, etc.) and the exact version.
  2. Update to a fixed version. Move to 8.5.12, 8.4.27, 8.3.36 or 8.2.35 through your distro packages, official builds, or your platform's managed PHP. Restart workers after the upgrade so old processes die.
  3. Prioritise internet-facing first. Public WordPress and APIs before internal tools. Anything with no auth in front of PHP goes to the front of the queue.
  4. If you cannot patch EOL PHP, take it offline. CISA's guidance is blunt: if you cannot update an internet-facing system, pull it off the internet until you can. A temporary maintenance page beats a shell on the box.
  5. Use temporary WAF rules only as a bridge. A WAF may blunt some opportunistic probes, but it is not a substitute for a fixed runtime. Plan the patch window; do not live on WAF hope.
  6. Watch for odd worker behaviour. At a high level, CISA recommends monitoring for PHP workers that start spawning shells or otherwise behaving like a compromised process. Unusual child processes, unexpected outbound connections from the PHP user, and sudden file writes under the docroot are the kinds of signals ops teams already watch — lean on them harder this week.

On the server (SSH or your host's terminal):

php -v

Or drop a temporary phpinfo() page on a non-public host, confirm the version and SAPI, then delete the file. You want one of the fixed builds above (or a vendor build that clearly documents the php2shell backports).

Why this matters for Hackup's readers

A lot of the web still runs on PHP. In India especially, cheap shared hosting and long-lived WordPress sites mean "we'll upgrade next quarter" is a common habit. Unauthenticated RCE in the language runtime is the opposite of a niche bug: scanners will eventually try every open port 80/443 they can find. Patching is cheaper than incident response.

Also remember the ethical line we keep on this blog. Understanding that OOM interrupts and stale globals are dangerous is useful for defenders and for people learning secure coding. Turning that knowledge into an attack against someone else's server is a crime. Learn on your lab VMs. Patch production. Leave other people's boxes alone.

Official sources

Patch first, learn second

php2shell is a loud reminder that the language runtime is part of your attack surface. Inventory, upgrade, restart, verify with php -v, then breathe. After the dust settles, read the Foundation's write-up on how they are strengthening PHP security going forward — that is the learning part. The patching part should already be done.

If you maintain PHP for a team or a client and want a second pair of eyes on a version checklist (still defence only), leave a comment. Stay safe, and keep the lab experiments on machines you own.

— Ankur Mehta, Hackup's

Comments

Popular posts from this blog

Security Testing for QA Engineers: A Practical Guide

Artificial Intelligence: An Economic Disaster?

Virus Code In C++