Critical PHP vulnerability (PHP2Shell, 21 October 2026): is your website patched?

Check and fix

PHP2Shell workarounds explained: what session.upload_progress, memory_limit and a firewall actually do

PHP's security advisory of 21 October 2026 is unusual in one respect: alongside the fixed releases it lists a set of interim measures, and it says plainly that they reduce exposure but do not make an installation safe. Since then the measures have been copied into countless blog posts and support tickets, often without the conditions that make them work.

This article goes through them one by one. The source is the php.net advisory itself; we add nothing it does not say.

Two bugs, two kinds of workaround

PHP2Shell is two vulnerabilities with different mechanics, and the workarounds map onto them separately.

  • CVE-2026-109619 concerns request-owned internal state that can survive after its memory has been freed, with the session upload-progress feature as the reachable path. A later request handled by the same worker can then use that stale state.
  • CVE-2026-109618 concerns out-of-memory conditions. When PHP aborts a request because it ran out of memory, request memory can be left partly initialised, and cleanup can treat that bad data as valid.

Settings that help against one do nothing against the other, so you need both groups.

Workarounds for CVE-2026-109619

session.upload_progress.enabled = 0. This disables the feature that the known attack path goes through. Three conditions matter:

  1. Set it in php.ini, in the PHP-FPM pool configuration or in the web server's PHP configuration. The advisory is explicit that ini_set() in application code and .user.ini files are not enough, because the feature runs before that code has a chance to execute.
  2. Restart every PHP worker afterwards. Configuration loaded at start-up does not change for running processes.
  3. Check that nothing in your application relies on upload progress bars. Few modern applications do.

On PHP 8.5: fatal_error_backtraces = 0, then restart the workers. This setting does not exist on older branches.

Remove invalid or deprecated per-request settings that emit diagnostics before initialisation, for example obsolete directives in .htaccess or .user.ini. Suppressing the messages with error_reporting, display_errors or @ does not help; the setting has to go.

Fix fatal errors and execution timeouts that an attacker can trigger. Any request path that reliably ends in a fatal error or a timeout is a candidate for the attack, so this is a good moment to clear the error log of recurring fatals.

Workarounds for CVE-2026-109618

memory_limit = -1. Counter-intuitive, but the point is that the dangerous condition is PHP hitting its own memory limit mid-request. Removing the limit removes that path. Set it with php_admin_value in the FPM pool or in the Apache configuration, so the application cannot restore a finite limit, and check that no other configuration layer sets one.

Removing the memory limit shifts the job of containing a runaway request to the layer around PHP:

  • post_max_size: 8M if the site takes no uploads, 32M if it does, with upload_max_filesize kept below post_max_size.
  • Request limits at the web server or proxy, including for requests that do not send a usable Content-Length. In Nginx that is client_max_body_size; in Apache LimitRequestBody.
  • A container or cgroup memory limit that kills only the affected worker when it misbehaves. The advisory warns specifically against RLIMIT_AS and RLIMIT_DATA, because those produce exactly the in-process out-of-memory condition the bug needs.

What a web application firewall adds

A WAF in front of the site can block the request patterns that are known to trigger the bugs, and vendors have shipped rules. That is useful as a second layer. It is not a fix: rules match known patterns, and the underlying bug is still present for any pattern the rules do not cover. Treat a WAF rule as something that buys hours or days, not as a reason to postpone the update.

The 23 October follow-up

On 23 October PHP added an informational advisory (CVE-2026-115560). Applications that switch session.serialize_handler at runtime, from php_binary or php_serialize to php, should keep session.upload_progress.enabled = 0 until the next bugfix release. If your application does this, which is rare, keep the workaround in place even after updating.

Why none of this replaces the update

Every item above narrows the paths an attacker can use. None of them removes the bug. The advisory's wording is that only an update is a complete fix, and that remains the case after every workaround is applied. Use the measures to cover the gap between now and the maintenance window; do not let them become the plan.

For sites on PHP 8.1 or older, where no release exists, the workarounds buy time for an upgrade to a supported branch. That upgrade is described in our end-of-life article.

If you want these settings reviewed on your own hosting, or the update done, send us your website address and hosting provider.

LET’S MAKE YOUR NEXT MOVE

Ready to move your
business forward?

Tell us where you want to go. We can help you shape the website, application or integration to get started.

Let’s talk about your project
Chat on WhatsApp