PHP2Shell_option2_4K

Initial Assessment – PHP2Shell: Two Critical Unpatched PHP RCEs (CVE-2026-109618 & CVE-2026-109619)

October 21, 2026

Initial Assessment – PHP2Shell: Two Critical Unpatched PHP RCEs (CVE-2026-109618 & CVE-2026-109619)

Book A Demo
See how Upwind uses runtime context to turn cloud security fingdings into real-time protection.
Book a Demo

TL;DR

PHP is releasing emergency fixes today for two critical use-after-free vulnerabilities in the session upload progress handler. Both allow remote code execution on default configurations and were leaked before the coordinated disclosure.

What’s happening?

The bugs live in php_session_rfc1867_callback (ext/session/session.c). PHP caches two zval * pointers (post_bytes_processed and current_file_bytes_processed) into HashTables while tracking multipart upload progress. A second request triggers session re-read and zend_hash_update, which destroys the HashTable via zval_ptr_dtor. The freed memory can then be reclaimed and controlled by the attacker.

How the attack works

An attacker sends a fast multipart POST that populates the cached pointers, followed by a second request that forces the HashTable destruction. After the free, the attacker places a controlled zend_fcall_info / zend_internal_function structure at the reclaimed address. The next use of the dangling pointer reaches zend_call_function, which can be directed at system() or equivalent.

The exploit requires the upload-progress key as a multipart form field (default name PHP_SESSION_UPLOAD_PROGRESS) before a file part. Stock php.ini is sufficient (session.upload_progress.enabled=1). The field name is configurable via session.upload_progress.name, so only the default is a reliable indicator.

Successful exploitation needs a per-build offset between zval_ptr_dtor and zend_call_function. A wrong offset or a lost heap race typically segfaults the PHP worker. When a proxy sits in front (nginx → php-fpm), this produces a 5xx (commonly 502). A correct offset that wins the race returns 200 and executes the payload. mod_php without a proxy often just drops the connection.

Independent research published confirmed the issue on stock PHP 8.4.4 and 8.2.34 and supplied a framework that extracts build-specific offsets, forges the body, and delivers the payload. PHP’s multipart parser is also looser than a simple line-based field matcher: it accepts folded headers, lines with no colon (glued to the previous header), Content-Disposition without form-data, missing spaces, and junk after the closing quote. Detection logic that only looks for a clean name=”PHP_SESSION_UPLOAD_PROGRESS” on a single line can be evaded.

Why this matters

  • Default configuration is vulnerable.
  • PHP powers a large fraction of the web (WordPress, Drupal, Magento, control panels, shared hosting).
  • Successful exploitation yields command execution as the PHP process user.
  • End-of-life branches (8.1 and earlier, 7.x, 5.x) will not receive official fixes.
  • Apply the official PHP security release as soon as it is available (targeted for today at 14:00 UTC). Expected fixed versions include the current supported branches (8.2–8.5).
  • Immediate mitigation: set session.upload_progress.enabled=0 in php.ini, .user.ini, or .htaccess.
  • Inventory every PHP installation (php-fpm, php-cgi, mod_php, control panels, Windows bundles, application-bundled PHP).
  • For detection, look for POST requests containing the upload-progress field (accounting for the parser’s loose header handling) and treat 5xx responses from PHP workers as a high-confidence crash signal of an attempted exploit. A 200 on the same pattern is the success case.
  • Isolate or upgrade any internet-facing end-of-life PHP.

The bigger picture

These are classic use-after-free bugs in a high-traffic request path. The leak forced an accelerated release, and the technical details (including the precise free and reclaim path plus the need for per-build offsets) are already public. Until systems are patched or the feature is disabled, any exposed PHP process that handles multipart uploads is a candidate for remote code execution.

Bottom line

Two critical use-after-free flaws in PHP’s session upload progress handling allow remote code execution on default configurations. Disable session.upload_progress.enabled now if you cannot patch immediately, apply the official release as soon as it drops, and treat end-of-life PHP as high risk.

Contents
Add the Upwind RSS Feed to Slack
Connect the Upwind RSS Feed to your Slack.
Follow the how-to here.
Threat RSS
Add the Upwind RSS Feed to Slack
Connect the Upwind RSS Feed to your Slack.
Follow the how-to here.
Main RSS