- Post History
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
2 hours ago - edited 58m ago
Authored by: Michael Freeman, Head of Threat Intelligence, and Guy Broder, Sr. Director, Product Management
On October 20, 2026, details of two critical vulnerabilities in PHP leaked and began circulating ahead of their scheduled disclosure. The vulnerabilities are tracked as CVE-2026-109618 and CVE-2026-109619 and known collectively as PHP2Shell, with each flaw identified as CVSS v4.0 9.2. These are critical remote code execution vulnerabilities in a popular programming language, posing a significant risk for a large share of websites and hosting platforms. PHP users are advised to update immediately.
The bottom line: These unauthenticated vulnerabilities could lead to stolen data or site takeovers, allowing attackers to run their own code or commands of their choosing on the server. Organizations must act immediately, inventory all PHP installations, prioritize internet-facing systems, and update to a fixed version. Isolate or disable externally accessible PHP services that cannot be updated immediately. Where compromise is suspected, preserve volatile evidence before restarting or patching.
Overview and Impact
PHP is a scripting language embedded across a large share of the web, used to build dynamic websites, container base images, and web applications. It powers content management systems, shared hosting platforms, control panels, and many applications that do not advertise that they run PHP underneath. Because these flaws sit in PHP’s core rather than in a single application, the number of places an organization needs to check for vulnerable PHP is large.
The flaws affect every PHP install serving web requests: PHP-FPM, Apache mod_php, php-cgi, FrankenPHP, and LiteSpeed. PHP rates mod_php highest risk, because a demonstrated exploit triggers before any application code runs.
Understanding the root cause
- CVE-2026-109618, RCE via OOM corruption: an out-of-memory error can stop PHP while request data is only partly set up, and cleanup then treats it as valid. In some contexts, especially early request handling such as multipart parsing into $_POST/$_FILES), request memory can be reachable but only partially initialized when an allocation fails.
- CVE-2026-109619, RCE via stale global state: Global state (error/backtrace, session, object, extension, serialize/unserialize) owned by one request can survive after its memory is freed, due to fatal errors skipping reset or non-fatal diagnostics repopulating after cleanup. A later request on the same worker reads or branches on the stale pointers before normal initialization.
Both vulnerabilities stem from PHP’s historical use of longjmp() for fatal errors (including out-of-memory) and incomplete cleanup of request-owned or global state that persists across requests on the same worker process. This creates use-after-free (CWE-416), uninitialized pointer access (CWE-824), and related issues. Confirmed impacts include unauthenticated RCE as the web worker user, memory disclosure (e.g., passwords, tokens, keys from other requests, similar in impact to Heartbleed in some paths), and related DoS conditions. Early exploitation was reported (including by Cloudflare) before and immediately after the October 21, 2026 patch release; mass scanning and attacks were expected.
Armis VMDR CVE story timeline and associated risk score.
Mitigation and Defense Strategy
All PHP users are strongly encouraged to update immediately to address the potential unauthenticated remote code execution in PHP 8.5.12, 8.4.27, 8.3.36, and 8.2.35.
What you should do now:
- Update to a fixed version. Secure downloads are available on the PHP downloads page.
- Use patched packages from your Linux distribution or LTS vendor, which received the fixes in advance.
- Inventory every PHP install, web servers, vendor appliances, and anything running WordPress, Drupal, Joomla, or Magento. Identify any end-of-life environments for additional risk, as versions 8.1 and older are no longer updated.
- Capture volatile evidence before patching on any suspected host. Restarting workers wipes the in-memory state that CVE-2026-109619 abuses. Collect memory from the PHP worker processes and the web server, plus the process tree, network connections, and open files, then patch.
- Restart PHP-FPM and Apache and rebuild container images.
- Where possible, turn off external PHP sites until an update is possible.
- Patch internet-facing systems first. Isolate any affected servers or legacy environments.
Guidance for Armis Customers
Detection for the affected version is in place. Please use the sample queries below to find affected assets with Armis (ASQ):
- Devices affected by the CVEs
- in:devices vulnerabilities:(id:CVE-2026-109618,CVE-2026-109619)
- in:devices vulnerabilities:(id:CVE-2026-109618,CVE-2026-109619) !publicIp:(<EMPTY>)
- Every device running PHP
- in:devices application:(name:%PHP%)
- End-of-life PHP (no fix expected)
- in:devices application:(name:%PHP% version<8.2)
Armis VMDR product visualizing the
Interim mitigation, if patching is not immediately available:
Interim mitigations should be explored only where you cannot patch today, and do not count as a fix. Any unpatched hosts should be treated as exposed.
|
Interim: CVE-2026-109618 |
Set and enforce memory_limit=-1 via php_admin_value. This removes the predictable per-request limit used in confirmed exploits but is incomplete (other allocation failures can still longjmp). Do not rely on RLIMIT_AS/RLIMIT_DATA (they force mmap failures that hit the vulnerable path). Prefer cgroup/container memory limits that kill only the offending worker. Keep post_max_size low (e.g., 8M without uploads, 32M with) uploads, and upload_max_filesize below it. Enforce request, size, number of fields/parts/headers and nesting depth at the web server, reverse proxy, or WAF. If multipart is unused, block it at the frontend. |
|
Interim: CVE-2026-109619 |
Set session.upload_progress.enabled=0 in php.ini or the server config —not via ini_set() or .user.ini, as it must take effect before request parsing). Restart workers. On PHP 8.5, set fatal_error_backtraces=0. Eliminate attacker-reachable fatal errors, parse failures, uncaught exceptions, timeouts, and diagnostics during early initialization or cleanup (including invalid/deprecated per-request INI settings that emit warnings before script execution). Prefer static/startup configuration. Additional hardening: session.use_only_cookies=On, session.use_strict_mode=On, consistent session.serialize_handler across directories, and consider pm.max_requests=1 in FPM for frequent recycling (operational cost). |
The following measures reduce exposure but do not make an installation safe:
- WAF rule updates (temporary, can break legitimate uploads): Review and tune web application firewall rules to cover newly disclosed exploit patterns and confirm that managed rule sets are current and that blocking rules aren’t generating unacceptable false positives.
- If you cannot patch quickly: Take systems offline or restrict to GET/HEAD if you cannot update. Verify the effective configuration from a web-served request (not CLI PHP), as configurations often differ.
- Tighter ingress security groups: Restrict inbound access on internet-exposed endpoints to only the sources, ports, and protocols they need, and remove any broad rules such as 0.0.0.0/0 on administrative or backend services.
- Check whether vulnerable PHP is running in memory or only on disk: Confirm which PHP binaries and modules are actually loaded by running processes, not just installed on the filesystem. A patched file on disk doesn’t help if the old code is still in memory, so a service restart may be needed after patching.
- Hunt in the logs, beginning well before October 20. Look for:
- Large or malformed multipart POSTs, high part or field counts, and chunked requests with no content-length, sent to any .php path
- Repeated “allowed memory size exhausted” fatals and execution timeouts in error logs
- Worker segfaults or crash/respawn bursts in FPM and Apache error logs
- Odd session files in the session save path.
Long-term defensive actions:
- Identify unexpected child processes: Alert when the PHP process or web server spawns shells (such as sh, bash, or cmd) or utilities that PHP applications don’t normally launch.
- Reverse shells: Detect outbound connections initiated from web server processes to unfamiliar external addresses, especially those followed by an interactive shell.
- Unusual outbound traffic: Baseline normal egress from web-facing hosts and flag new destinations, unusual ports, large data transfers, or connections at atypical times.
- Rotate credentials: Assume anything the PHP process could read is exposed on any host with indicators. Consider proactive rotation for internet-facing hosts that stayed unpatched after October 20.
Indicators of Compromise (IOCs)
Attacks are unauthenticated and often pre-application-code. Organizations should also hunt for evidence of attempted or successful exploitation by monitoring for:
- Network / request indicators:
- Multipart/form-data POSTs (or PUT/PATCH) containing PHP_SESSION_UPLOAD_PROGRESS (or configured name), especially with deep nesting (e.g., many [] levels), large or stalled bodies, missing/invalid Content-Length, or combined with body-supplied PHPSESSID.
- High volume of such requests from single sources, or unusual paths (any PHP endpoint can be targeted).
- WAF/IDS signatures for the above field, oversized multipart, or known PoC patterns. Log (do not solely rely on blocking) matches involving the progress field + session identifiers.
- Application / PHP logs:
- Memory exhaustion messages (“Allowed memory size”, hard limits).
- Early diagnostics / warnings before script execution (“in Unknown on line 0”, invalid INI, extension config issues).
- Fatal errors, parse errors, or timeouts on attacker-controlled routes, especially around upload, import, or session paths.
- Session-related warnings (illegal session IDs, etc.).
- Spikes in 500 responses correlating with the above.
- Host / process indicators:
- Anomalous PHPSESSID cookies (high entropy, encoded heap-like data, or unexpected values—memory disclosure path).
- Persistent file locks (flock) on session files (sess_* under session.save_path); check /proc/locks or equivalent. Worker hangs without crashes.
- Worker pool exhaustion or abnormal recycling.
- Unexpected processes or shells under the web user after suspicious multipart activity.
- Session files containing injected PHP code or serialized objects (scan for upload_progress_ prefixes or <?php in session storage).
- Behavioral:
- Correlate multipart requests with subsequent memory disclosure in responses, unexpected code execution, or lateral movement from the web user.
- Endpoint detection for PHP process behavior (inline command execution patterns, etc.).
Why Continuous Visibility Matters
This disclosure shows how quickly vulnerability information can surface before patches are available. The window between disclosure and remediation is when exposure accumulates. Organizations that cannot quickly answer where PHP runs, including inside vendor software and appliances, must start that inventory under pressure. Point-in-time checks are not enough when the most common gap is not knowing an instance exists.
PHP2Shell reinforces a recurring security lesson: remediation starts with knowing where affected technology exists. Continuous monitoring and visibility into assets and their vulnerability status, knowing what you have, what is exposed, and what attack pathways exist into your organization, is what allows teams to act within hours rather than days.
Resources:
PHP: https://www.php.net/archive/2026.php#2026-10-20-1
https://www.php.net/archive/2026.php#2026-10-21-5
Github: https://github.com/php/php-src/security/advisories/GHSA-w8hw-w9fx-j79w
https://github.com/php/php-src/security/advisories/GHSA-6wmf-4rv5-p3rp
Huntress: https://www.huntress.com/blog/php2shell-leaked-critical-php-vulnerabilities
watchTowr: PHP Remote Code Execution FAQ: CVE-2026-109618 & CVE-2026-109619
