All Articles
Security Incident Report
7 min

php2shell Incident Report

Fabian Golle
October 22, 2026
php2shell Incident Report

On the afternoon of October 21, 2026, the fix versions for php2shell were released. About ten minutes later, the patched PHP version was already running on the first production systems we operate. This isn't a heroic tale — it's the result of a day our entire team spent in incident mode, from early morning until late at night.

Two critical vulnerabilities in the PHP core, CVE-2026-109618 and CVE-2026-109619, quickly dubbed "php2shell." Pre-auth remote code execution, CVSS 4.0 score: 9.2. In plain terms: an attacker doesn't need a login or a password to execute their own code on the server.

If you run a website, an online shop, or a portal built on PHP, this affects you. This article is a field report: what we saw, what we did, what we found, and what you should check right now.

What php2shell Is

Two vulnerabilities, two mechanisms, one shared outcome.

CVE-2026-109618 is a memory corruption issue in the processing of multipart uploads — exactly the process that occurs when someone sends a file to your application through a form.

CVE-2026-109619 stems from "stale global state" — a global state that isn't reset correctly. A confirmed path to code execution exists through this flaw, specifically via the PHP function session upload progress. It writes the progress of ongoing file uploads to the session, is rarely used intentionally, and yet remains active on many installations.

The key point for decision-makers: these vulnerabilities don't sit in WordPress, Shopware, Symfony, Laravel, or your custom-built application. They sit in PHP itself, one layer below. That means virtually all PHP web applications are affected, including those running on the end-of-life versions 7.x, 8.0, and 8.1, which no longer receive patches.

Why This Vulnerability Was Different

Security researcher Kevin Beaumont told Help Net Security that this was one of the biggest vulnerabilities in years. Help Net Security also pointed out that the attack succeeds before any application code even runs; setups using mod_php are considered especially exposed.

The consequence: well-maintained application security only helps so much here. Strong passwords, two-factor authentication, or an up-to-date CMS release only come into play once PHP has already processed the request. In the end, the only effective protection is the PHP update itself.

The Day Didn't Go by the Book

Details about the vulnerability leaked before the official release, so the release was moved up by a day because of the leak. For defenders, that meant attackers had information before a fix even existed.

The fix versions were released in the afternoon: 8.2.35, 8.3.36, 8.4.27, and 8.5.12. That same day, security firms — including watchTowr and Cloudflare — confirmed active exploitation "in the wild." By evening, public exploit code had surfaced. Media outlets, including Germany's FAZ, also reported on it.

Package Sources Under Strain

On top of that came a bottleneck that's often underestimated on days like this: the package sources many operators rely on to update PHP were overloaded all day — including the widely used Ubuntu PPA. For many, updates arrived late. Distributions like AlmaLinux also reported that patched packages were still being built.

You can't patch what isn't available yet. Anyone relying solely on distribution packages was stuck in a window where the vulnerability was being actively exploited and the update hadn't yet arrived.

Our October 21

No customer names, no internal details — but here's how it unfolded.

Situational Awareness Instead of Gut Feeling

We tracked the situation live and automatically all day, monitoring more than 20 sources in parallel: php.net, the PHP source repository and security advisories, NVD, CISA KEV, the distributions' package sources, Hacker News, Reddit, Mastodon, security firms' technical blogs, and Google News.

Alongside that, we worked with our own data: server and access logs from all systems we manage, plus an automated check of every running application instance for suspicious processes, files, and connections — every five minutes, all day long.

The goal: to be able to answer two questions at any moment. Has the threat landscape changed? And has anything changed on our systems?

Inventory: Who's Affected?

Before you act, you need to know what you're dealing with. We identified all PHP applications belonging to our customers and prioritized them by risk: Is the system publicly accessible? Does it process file uploads — the attack vector in question? Does it run on our infrastructure or a third party's?

For systems under our management, we could act directly. For systems hosted elsewhere, we informed the relevant parties, asked questions, and coordinated interim measures.

Before the Patch: Narrowing the Attack Surface

Between "there's a vulnerability" and "there's a fix" lies the real work.

  • Moving staging and test systems behind the firewall. They're often publicly accessible and rarely maintained with the same attention as production systems.
  • Selectively blocking or further securing file uploads, depending on how critical that function was for each operation.
  • Hardening the PHP configuration, including setting session.upload_progress.enabled = 0. This disables the exact feature behind the confirmed attack vector.
  • Preparing emergency PHP builds from source code, so we wouldn't be dependent on overloaded package sources.

The Patch

When the fix versions were released, the first production systems were updated roughly ten minutes later, and every system we operate was updated that same afternoon and evening.

Then came the part that incident reports often leave out: the controlled rollback. Blocked uploads were re-enabled, temporary restrictions were lifted, and every change was documented. An incident isn't over once the patch is running — it's over once the infrastructure is back in a defined, stable state.

Analysis: Verify, Don't Assume

Afterward, we checked logs, file systems, processes, and network connections, looking for the typical traces of successful exploitation: modified or new files in web directories, processes that didn't belong there, unusual outbound connections, and suspicious patterns in access logs.

The result, stated deliberately and precisely:

We found no evidence of successful exploitation of the vulnerabilities.

That's a statement based on the data we reviewed. After a critical pre-auth RCE vulnerability, that's the most anyone can responsibly claim.

Communication

We proactively informed affected customers in the morning, kept them updated with interim status reports throughout the day, and gave the all-clear by evening. For customers hosted with third parties, we provided support: informing their hosts, coordinating interim measures, and reviewing logs wherever we had access.

Our experience: on a day like this, executives don't need CVE details — they need three answers. Are we affected? Did anything happen? When will it be resolved?

The Most Common Misconception: "Our Hosting Provider Handles That"

Sometimes that's true. Often, it's less clear-cut than it sounds. Take an example from Laravel Forge's documentation: Forge's automatic security updates don't patch PHP, because PHP comes from its own package repository there, and Ubuntu's unattended upgrades only install updates from Ubuntu's own security repository.

So the real question isn't whether you have "automatic updates," but whether PHP itself is actually covered by them. That can be clarified — but only if someone specifically asks.

Then there's the end-of-life scenario: PHP 7.x, 8.0, and 8.1 no longer receive patches. If you're running on one of these, you don't have an update task — you have a migration project.

What You Should Do Now

  1. Check and update your PHP version to 8.2.35, 8.3.36, 8.4.27, or 8.5.12 (or the patched packages for your distribution).
  2. Managed hosting: Your provider is responsible — but ask proactively anyway, and get confirmation that the update has been applied.
  3. Your own servers (VPS, dedicated servers, Plesk): Act yourself, and do it urgently.
  4. PHP 7.x, 8.0, 8.1: No patch is coming. Plan your upgrade or migration now.
  5. Interim measures are only a bridge: session.upload_progress.enabled = 0, securing uploads, restricting access. These don't replace the update.
  6. Check your logs: Watch for anomalies in access logs, new files in web directories, and unusual processes.

Note: Test configuration changes in a staging environment first, since some applications depend on upload functionality.

Conclusion: Security Is an Ongoing Operation

What made the difference on October 21 wasn't improvisation — it was preparation: knowing what's running, continuously monitoring the situation, acting quickly and in a controlled manner, and communicating transparently. Security isn't a state you achieve once; it's an ongoing operational effort.

Not sure whether your PHP systems are affected? We can check on short notice. Get in touch now

Tags
cybersecurityphpcve-2026-109618cve-2026-109619incident-responsezero-dayhostingmanaged-servicesvulnerability-management

Sounds interesting?

Let's figure out together how we can move your project forward.

Schedule a call