Back to blog

PHP2Shell Vulnerabilities (CVE-2026-109618 & CVE-2026-109619): Analysis and Remediation

TL;DR: Critical PHP remote code execution vulnerabilities

The PHP project released fixes on October 21, 2026, for two critical vulnerabilities, CVE-2026-109618 and CVE-2026-109619. Each is rated 9.2 on CVSS v4.0 and can allow unauthenticated Remote Code Execution (RCE). These vulnerabilities are memory corruption bugs in PHP's underlying C runtime code, not in the web applications running on it, so the only complete fix is deploying a patched PHP binary build. Application-layer security tools, Contrast included, work above the interpreter layer and are not a substitute for the PHP runtime patch. To remediate these PHP2Shell vulnerabilities, update PHP today, starting with internet-facing systems.

Introduction

Two critical flaws, one runtime, and a very short window. When a vulnerability sits inside the interpreter that runs your web applications, every hour between disclosure and patch is an hour attackers can use. Security vendors have already reported attack attempts. PHP and CISA had not confirmed exploitation in the wild at the time of writing, but you should assume attempts are underway.

Security teams are tired of emergency patch weekends. This one is still worth the effort.

What is PHP2Shell and why it matters

PHP2Shell is the name being used for a pair of critical security vulnerabilities in the core PHP runtime interpreter. The PHP project published fixes for both CVE-2026-109618 and CVE-2026-109619, stating that updating the underlying interpreter is the only safe choice.

Unauthenticated remote code execution is the worst class of web vulnerability. An attacker doesn't need a login, stolen credentials, or a user to click anything. If an attacker can reach a vulnerable PHP runtime, they can try to run code on the host with the privileges of the web server process.

The impact by numbers

So far, the facts are short and sharp. There are two CVEs, each rated 9.2 on CVSS v4.0. There are four supported PHP branches with fixes, and everything on 8.1 or older is left without any update at all. We are deliberately not adding projected victim counts or loss figures here, because PHP’s advisory does not provide them and guessing would not help you.

Critical business consequences of unauthenticated remote code execution can include the following.

  • Full compromise of the web server and anything it can reach
  • Data theft from databases and file stores the application connects to
  • Webshells, malware and persistent access installed for later use
  • Lateral movement into internal networks and cloud environments
  • Downtime, incident response costs and breach notification obligations

How the PHP2Shell exploit works

Both vulnerabilities are memory bugs in PHP’s underlying C code. They are not injection flaws in application logic, and they do not depend on a bug you wrote. That distinction matters because it decides which defenses can help.

PHP’s advisory ties CVE-2026-109618 to how the runtime handles large or malformed requests, which is why the interim guidance covers memory limits, request size, field counts and header limits. CVE-2026-109619 relates to stale request state, including session upload progress handling and fatal error and diagnostic paths, which is why the guidance covers disabling upload progress and removing settings that emit diagnostics. PHP lists the confirmed impact of CVE-2026-109619 as memory disclosure and remote code execution, both with web worker privileges. We are not going to speculate beyond what PHP has published.

The attack chain

In general terms, an attacker sends crafted requests to a reachable PHP endpoint and triggers the memory flaw. A successful attempt can lead to code running as the web server user. From there, the usual playbook follows. The attacker starts a shell or a download tool, pulls down a payload and opens an outbound connection. That is why we are pointing you to web server and PHP logs from October 17 forward. Look for web server processes starting shells, download tools or unexpected outbound connections. If you find any, isolate the host and start incident response.

The patching timeline challenge

Patching the interpreter is harder than patching an application dependency. PHP is often baked into base images, shared hosting, managed platforms and vendor appliances. Many teams do not control every runtime they depend on, and some do not have a complete list of where PHP runs.

There is also a version problem. PHP 8.1 and older no longer receive updates from the PHP project. Those hosts must be upgraded to a fixed branch, or you must ask your vendor whether a backported fix exists. For teams that build from source, PHP’s security team published minimal source backports for 7.4, 8.0 and 8.1. They did this because of the issue's severity. You can check which branches are still supported at endoflife.date/php.

Static analysis and SCA limitations

Scanning your application code will not tell you whether the PHP runtime underneath it is patched. The PHP interpreter is not an application dependency, so tools that analyze your source or inventory your libraries are looking at the wrong layer for this problem. The same applies to updating a framework. Upgrading WordPress or Laravel does not patch PHP.

The reliable way to find exposure is an infrastructure-level inventory of every host, container image and managed service that runs PHP, along with the running version on each one.

Web application firewalls are an added layer, not a fix

Some WAF and CDN providers have shipped emergency rules for these CVEs. Turn them on in block mode if you have them. They are worth having, but they are signature-based and can miss variants. Treat them as an extra layer that buys time and never as a replacement for the update.

Where Contrast fits and where it does not

PHP2Shell is a flaw in the C interpreter itself, and the interpreter sits beneath every layer that application security testing and protection tools can see. No application-level tool can patch a memory bug in the runtime, so deploying a patched PHP build is the primary security control and must come first.

Contrast works inside the application and watches how untrusted data reaches things like SQL queries and system commands. That is where injection, path traversal and other application-layer attacks get stopped, and those attacks don't pause while you patch the runtime. Attackers probing PHP hosts this week will also probe the applications running on them, so keep application protection in place while the update rolls out.

We also checked our own environment. Our customer-facing platform does not run on PHP, and we have not identified exposure. If you run the Contrast PHP agent, it lives inside your own PHP environment, so the update guidance in this post applies to the hosts where it runs.

Detection and remediation strategy

Addressing PHP2Shell takes a systematic approach and not just a scan. Here is the five-step strategy we recommend.

Step 1. Comprehensive discovery

Find every place PHP runs. That includes web servers, containers, CI images, staging environments, managed platforms and anything a vendor runs for you. Record the running version on each host, not the version you think you deployed. On Linux distributions, the version string may not show whether a fix is applied, because vendors often backport patches without changing it. Check your vendor’s package changelog or security advisory to confirm.

Step 2. Determine actual exposure

Rank hosts by reachability. Internet-facing systems come first, then internal systems that accept requests from untrusted sources. A vulnerable host no attacker can reach is lower priority than one exposed to the public internet.

Step 3. Strategic patching

Update to PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35, starting with internet-facing systems. Restart PHP-FPM or your web server afterward and confirm the running version. For PHP 8.1 and older, upgrade to a fixed branch or ask your vendor about a backport.

Step 4. Apply interim measures where you cannot patch today

CVE-2026-109618 (OOM corruption)

  • Set memory_limit=-1 where applications can’t override it, such as php_admin_value in the FPM pool or Apache config. This is partial, since an underlying allocation failure can still reach the flaw.
  • Set a low post_max_size (8M, or 32M if you need uploads) and enforce request size, field, part, header and nesting limits at your web server or proxy.
  • Don’t use RLIMIT_AS or RLIMIT_DATA, because they can trigger the flaw.

CVE-2026-109619 (stale global state)

  • Set session.upload_progress.enabled=0 in php.ini, the FPM pool or server config, then restart every worker. This blocks the confirmed session paths only.
  • On PHP 8.5, set fatal_error_backtraces=0 and restart every worker. This blocks the confirmed backtrace path only.
  • Remove invalid or deprecated per-request settings that emit diagnostics, and fix attacker-reachable fatal errors and timeouts.

None of these measures fully mitigate the flaws. Updating PHP is the only complete fix. Follow PHP’s official advisory, since this guidance may change.

Step 5. Continuous monitoring

Check web server and PHP logs from at least October 17 forward. Look for web server processes starting shells, download tools or unexpected outbound connections. Keep watching after you patch, because attempts will continue, and a host compromised before the update stays compromised after.

The persistent threat

Disclosure day is not the end of the story. Attackers keep scanning for unpatched runtimes long after fixes ship, and old PHP versions linger in production for years.

Why organizations remain vulnerable

Several factors contribute to ongoing exposure.

  • PHP often sits beneath other software, so teams forget it needs its own update
  • Updating an application framework does not patch the runtime
  • PHP 8.1 and older will never receive a fix
  • Vendors and hosting providers patch on their own schedule
  • Incomplete inventories leave forgotten hosts running old versions

Modern attack patterns

Attackers move quickly from disclosure to attempts. Automated scanning means attackers probe a newly published flaw across the internet quickly. That compresses the window in which a team can patch calmly.

Building long-term defense

Layered controls matter, and each layer has a specific job. Patching removes the flaw. A WAF or CDN rule can reduce exposure while you patch. Endpoint and host monitoring can give you visibility into rogue processes. Application-layer protection stops application-layer attacks. None of those layers fixes a memory bug in the interpreter.

Lessons for future vulnerabilities

Know where your runtimes are, and know their versions. Keep unsupported versions off production systems. Rehearse an emergency patch process before you need it. Be honest with your own stakeholders about what each tool does and does not cover.

Conclusion and next steps

PHP2Shell is a patching problem. The fix is a patched PHP build, and it must happen now. Be wary of any claim that a tool can stand in for the update, and that includes ours.

Your action plan

  1. Inventory every system that runs PHP and record the running version.
  2. Update to PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35, starting with internet-facing systems.
  3. Restart PHP-FPM or your web server and confirm the running version.
  4. Upgrade any host on PHP 8.1 or older, or ask your vendor about a backported fix.
  5. If you cannot update today, apply PHP’s interim measures and restrict access to the system.
  6. Confirm any WAF or CDN emergency rules are enabled in block mode.
  7. Review logs from October 17 forward and isolate any host showing signs of compromise.

PHP’s full advisory is at php.net. Questions go to your account manager or support@contrastsecurity.com.

Key takeaways

  • CVE-2026-109618 and CVE-2026-109619 each score 9.2 on CVSS v4.0 and can allow unauthenticated remote code execution.
  • The flaws live in PHP’s C code, not in your application, so updating WordPress or Laravel does not fix them.
  • Fixed versions are PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35.
  • PHP 8.1 and older receive no updates, so those systems need an upgrade or a vendor backport.
  • Interim measures reduce exposure to specific attack paths but do not make an installation safe.
  • No security tool, Contrast included, substitutes for the update.

Frequently asked questions

What is PHP2Shell and why is it so dangerous?

PHP2Shell is the name for two critical vulnerabilities in PHP’s C code, tracked as CVE-2026-109618 and CVE-2026-109619. Each is rated 9.2 on CVSS v4.0 and can allow unauthenticated remote code execution, which means an attacker may be able to run code on a vulnerable server without logging in.

How can I tell if my applications are vulnerable to PHP2Shell?

Check the running PHP runtime version across every host, container image, and managed service. If the version is older than 8.5.12, 8.4.27, 8.3.36, or 8.2.35 on its respective branch, or if it runs on PHP 8.1 or older, treat it as vulnerable to PHP2Shell. Remember that checking your web application framework version (such as Laravel or WordPress) does not reveal your underlying PHP runtime patch status.

What’s the difference between PHP versions?

PHP 8.5, 8.4, 8.3 and 8.2 have fixed releases, listed above. PHP 8.1 and older receive no updates from the PHP project, so you need to upgrade or use a vendor backport. See endoflife.date/php for support status.

Can Web Application Firewalls (WAF) protect against PHP2Shell attacks?

Partly, and only as an added layer. Some providers shipped emergency rules, but signature-based rules can miss variants. Confirm the rules are enabled in block mode and still update PHP.

Can eBPF or EDR protect against PHP2Shell attacks?

Not completely. eBPF tooling is designed for sampling and best-effort monitoring rather than guaranteed blocking, so it cannot provide a complete defense. EDR has a similar limit, since it can show you rogue processes but generally cannot reliably prevent the event. Update PHP in either case.

Does Contrast detect or block PHP2Shell?

Not directly. These flaws sit inside the PHP interpreter, below the application layer where Contrast operates, so patching PHP is the control. Contrast continues to protect your applications against attacks such as injection while you patch.

What are the patched PHP versions for PHP2Shell?

The official patched releases for supported PHP branches are PHP 8.5.12, PHP 8.4.27, PHP 8.3.36, and PHP 8.2.35. If you are running PHP 8.1 or older versions, those branches are end-of-life and will not receive official updates. Organizations running end-of-life versions must upgrade to a supported release branch or contact Linux distribution vendors to obtain backported patches.

Are application security tools or WAFs a replacement for the PHP2Shell patch?

No. Because CVE-2026-109618 and CVE-2026-109619 reside in the PHP interpreter's C code, application-level security tools, Web Application Firewalls (WAFs), EDR solutions and eBPF monitoring tools cannot patch the underlying memory flaw. While WAF signature rules and application security tools offer valuable defense-in-depth, updating the PHP runtime remains mandatory for full remediation.

What interim mitigations can be applied if immediate PHP patching is not possible?

Temporary workarounds reduce exposure to specific attack vectors but do not fully fix the flaws. For CVE-2026-109618, lower post_max_size and restrict request sizes at your proxy or web server. For CVE-2026-109619, disable session upload progress (session.upload_progress.enabled=0) and disable fatal error backtraces on PHP 8.5. Always prioritize upgrading the PHP runtime over temporary mitigations.

Robert Vamosi

Robert Vamosi

Sr Product Marketing Manager & CISSP

Enlarged Image