SolvirPHP Migration 中文

PHP2Shell (CVE-2026-109618 / 109619): who is affected and how to check and fix it

Key facts

What
Two memory bugs in the PHP core that let an attacker run code on the server, with the web worker’s privileges, without logging in.
Severity
CVSS 4.0 score 9.2, critical.
Difficulty
The CVSS vector rates attack complexity as high. Reliability depends on the PHP build, extensions and memory layout; more workers and traffic raise the number of attempts needed but don’t remove the flaw.
Disclosed
October 21, 2026, in PHP’s security advisories.
Affected
Every PHP 8.2, 8.3, 8.4 and 8.5 release below the fixed version.
Fixed in
8.2.35, 8.3.36, 8.4.27, 8.5.12.
Older versions
8.1 and earlier are end of life. There is no patch, and the advisories don’t say whether they are affected, so assume they are.
Exploitation
As of October 22, 2026, CISA’s assessment in the CVE record lists no known exploitation.

What the two flaws are

CVE-2026-109618 ("RCE via OOM corruption"): when PHP runs out of memory it aborts the current request. In some places the abort leaves request memory half-initialized, and the cleanup that runs afterwards reads it, which an attacker can turn into code execution. The demonstrated trigger is a crafted file upload request (multipart/form-data) that exhausts memory while PHP parses the body, before any of the site’s own code runs.

CVE-2026-109619 ("RCE via stale global state"): one PHP worker handles many requests in turn. Some global state from a previous request is not reset and still points to freed memory. When the same worker handles the next request, it reads that state before initialization, which can lead to code execution or leak memory contents.

Both flaws are in PHP itself, not in WordPress or Laravel, so changing CMS or framework doesn’t fix them. Whether a site can be exploited depends on the PHP version and how PHP is run, and in some setups on the site’s own code (see the table below).

Which sites are affected

First, the PHP version:

BranchUpgrade to
8.2.x≥ 8.2.35
8.3.x≥ 8.3.36
8.4.x≥ 8.4.27
8.5.x≥ 8.5.12
8.1 and olderNo patch

Then how PHP is run, which changes the risk a lot:

How PHP runsStatus
Apache + mod_phpRemote code execution for CVE-2026-109618 was confirmed with default input and memory limits, and it happens before the site’s own code runs, so no bug in the site is needed. CVE-2026-109619 was also confirmed on mod_php, and its upload progress path doesn’t depend on site code either. Highest risk of these setups.
PHP-FPM (Nginx and others)CVE-2026-109619 was confirmed to allow code execution on FPM when the site has a suitable code path. For CVE-2026-109618 on FPM there is source analysis but no complete exploit yet.
FrankenPHPPHP’s source analysis says it behaves like mod_php, so CVE-2026-109618 is likely exploitable without relying on site code; this is not yet confirmed. For CVE-2026-109619 no equivalent trigger was found in the default configuration, which PHP says doesn’t make it immune.
LiteSpeed (LSAPI)PHP says it behaves like FPM and is likely affected, not yet confirmed.

How to check whether your site is affected

  1. Put a temporary file in the web root containing only <?php phpinfo();, open it in a browser and look at "PHP Version" and "Server API" at the top. Delete the file right after, since it exposes server details.
  2. "Server API" of Apache 2.0 Handler means mod_php, FPM/FastCGI means PHP-FPM, and anything starting with LiteSpeed means LSAPI. For other values, check the documentation of your runtime.
  3. php -v on the command line shows the CLI build, which may not be the one serving your site. Trust phpinfo.
  4. If PHP comes from your distribution (Ubuntu, Debian, CentOS and so on), the fixed package usually keeps the old version number because the patch is backported. Check whether your distribution’s security notice lists these two CVEs and whether your installed package is at or above the fixed package version.
  5. If you use the official php Docker image, a tag like 8.3 doesn’t mean the latest patch. Run php -v inside the container or pull the image again.

How to fix it

Upgrading to a fixed release is the only complete fix.

  • Built from source or using the official Windows builds: upgrade to the fixed release of your branch (8.2.35, 8.3.36, 8.4.27, 8.5.12) or later.
  • Using distribution packages: update the PHP packages as described in your distribution’s security notice. Using a third-party repository (such as sury or Remi): update as that repository describes.
  • Using Docker: switch to the fixed image tag, rebuild and restart the containers.
  • On shared hosting or a server panel: switch to the fixed version in the panel. If it isn’t offered yet, ask your host.
  • After upgrading, restart every PHP process (php-fpm, Apache, LiteSpeed, FrankenPHP and so on), confirm the version with phpinfo, then delete the phpinfo file.
  • Still on 8.1 or older: there is no patch. Upgrade to a fixed 8.2+ release, or move the site to a different stack.

If you can’t upgrade yet

These come from PHP’s advisories. They reduce the risk but don’t replace the upgrade. Restart every PHP process after changing the settings.

There is no generic configuration mitigation that covers every CVE-2026-109619 path. The settings below for it each close only one confirmed path, other paths may exist in the application or extensions, and they may leave no log entry. Only upgrading is reliable.

  • (CVE-2026-109618) Set memory_limit=-1 in php.ini or the PHP-FPM pool and enforce it with an admin-level setting (php_admin_value[memory_limit] = -1 in an FPM pool). Then confirm no pool, directory or application setting (for example ini_set or .htaccess) puts a finite limit back. This removes the predictable per-request limit the flaw relies on, but it is not a complete mitigation: if a lower-level allocation fails, the vulnerable path can still be reached. The trade-off is that one request can use all memory. A container or cgroup memory limit can act as a backstop, but it doesn’t guarantee protection and can kill the master and every worker at once. Don’t limit memory with RLIMIT_AS or RLIMIT_DATA (such as ulimit -v): allocations then fail at the limit, which is exactly the vulnerable path.
  • (CVE-2026-109619) Set session.upload_progress.enabled=0. This blocks the demonstrated upload progress path but not other paths. Few sites use the feature; if yours shows an upload progress bar, it will stop working. It can stay off after upgrading too.
  • (CVE-2026-109619) On PHP 8.5, set fatal_error_backtraces=0. This removes the step that leaves stale state in the confirmed mod_php exploit path. It doesn’t cover other paths.
  • (CVE-2026-109618) If no form on the site uses multipart/form-data (file uploads included), block those requests at Nginx, your CDN or WAF. If the site needs them, keep post_max_size small, lower max_input_nesting_level, cap the number of input variables and uploaded files, and also limit the body size, the number of multipart parts and the headers per part at Nginx or your CDN, because a request without a declared length can bypass post_max_size. These are worth keeping after upgrading.
  • (CVE-2026-109619) Move per-request PHP settings (Nginx PHP_VALUE, Apache php_value and .htaccess) into php.ini or the FPM pool, and fix every directive that raises a warning or deprecation notice (deprecated or invalid values). These apply before request startup, and the warnings they raise are one of the triggers for this flaw.
  • (CVE-2026-109619) Remove fatal errors an attacker can trigger (upload, import, error-page and plugin paths), and don’t let requests reliably reach Maximum execution time exceeded. Changing the time limit only removes that one interruption.
  • (CVE-2026-109619) If performance allows, set pm.max_requests=1 in PHP-FPM so each worker handles a single request.

How to review logs and check whether you were attacked

PHP recommends turning on full logging in startup configuration (log_errors=On, error_reporting=E_ALL and a working error_log), ideally in an isolated audit. The main purpose is to find the errors and warnings that make the flaws reachable and fix them; seeing them doesn’t mean you were attacked. The advisory focuses on:

  • Warnings and deprecation notices that repeat before your scripts run.
  • Out-of-memory errors such as Allowed memory size of … bytes exhausted, especially clustered on upload requests. Large files and plugins cause these too, so this alone doesn’t mean an attack.
  • Maximum execution time exceeded and other fatal errors.

The next two are not from the advisory; they are general compromise checks:

  • Workers dying in PHP-FPM or Apache logs, for example on signal 11.
  • PHP files you don’t recognize, modified files, and unfamiliar cron jobs or processes. These are common signs that code was executed.

Fixing the errors you find reduces exposure, but changing error_reporting, using @ or turning off display_errors does not protect against these flaws, so don’t rely on hiding warnings. Clean logs don’t prove you’re safe either: older logs may not have recorded these levels, and an attack can finish before PHP writes anything.

FAQ

I run WordPress. Do I need a WordPress patch?

No, you need to upgrade PHP. The flaw is in PHP itself, so WordPress and plugin updates won’t fix it.

My site is behind Cloudflare or another CDN. Am I safe?

Not necessarily. CDNs forward upload requests to your server by default. Unless you block upload requests at the CDN or WAF, attack requests still reach PHP.

I’m on PHP 7.4. Am I affected?

The advisories only list the supported branches, 8.2 to 8.5. 7.4, 8.0 and 8.1 are end of life and won’t be patched. PHP doesn’t say whether they are affected, so it’s safer to assume they are.

What should I do on shared hosting?

Check the PHP version in your hosting panel and switch to a fixed version if it’s offered. If not, ask your host when they will upgrade.

Will upgrading PHP break my site?

Patch upgrades within a branch (say 8.3.30 to 8.3.36) usually don’t change behavior and are low risk. Moving to a newer branch, for example from 7.x or 8.1, can require code changes, so try it on a staging copy first.

Sources

Need a hand?

We can check whether your site is affected, upgrade PHP, or move a site stuck on an old version to a different stack. Leave your email and we’ll reply within 2 business days.

Used only to reply with your results. No marketing emails.