PHP2Shell Exploitation Turns Runtime Patching Into Incident Response
Two PHP runtime flaws allow unauthenticated code execution. Fix the runtime, restart every worker, and investigate activity from at least October 17.
PHP released 8.5.12, 8.4.27, 8.3.36, and 8.2.35 on October 21 to fix CVE-2026-109618 and CVE-2026-109619, two critical runtime flaws that can lead to unauthenticated remote code execution. The first turns an out-of-memory bailout during request processing into invalid memory handled at shutdown. The second lets request-owned state survive after its memory is freed and reach a later request handled by the same worker. Both sit below ordinary application authorization, so updating a CMS, framework, or plugin does not remove the vulnerable runtime.
The response is already an incident task, not a routine maintenance item. Amazon Threat Intelligence says its MadPot sensors received a PHP2Shell exploit attempt on October 17, four days before public disclosure, and saw broader exploitation after the embargo lifted. Cloudflare separately says it observed attack traffic and changing payloads. Administrators should inventory every PHP execution path, apply an upstream or vendor-backported fix, restart all workers, verify the live binary rather than a package manifest, and review evidence from at least October 17 on exposed systems.
Key Takeaways
- check_circle The fixed upstream releases are PHP 8.5.12, 8.4.27, 8.3.36, and 8.2.35; PHP 8.1 and older require a supported distributor or LTS backport, or migration to a supported branch.
- check_circle CVE-2026-109618 can reach confirmed code execution against Apache mod_php before application code runs, which means application-level validation is not a reliable boundary.
- check_circle CVE-2026-109619 crosses request boundaries through stale global state; confirmed paths include mod_php and PHP-FPM, and successful requests must land on the same worker.
- check_circle Amazon reports an exploit attempt dated October 17 and broad exploitation after disclosure, while noting that the earliest sensor attempts were not proven successful on real systems.
- check_circle A WAF can reduce exposure while deployment catches up, but PHP and Cloudflare both state that filtering is not a complete replacement for the runtime update.
- check_circle Installing a package is incomplete until Apache, PHP-FPM, containers, and any embedded PHP workers have been restarted and the running process reports a fixed build.
Exploitation Started Before The Public Patch Window
The PHP security team gave advance notice on October 20 that an emergency release would arrive at 14:00 UTC the next day. The notice described two CVSS v4.0 9.2 vulnerabilities but withheld technical details so operators and distributors could prepare without publishing an exploit recipe. When the release landed, PHP identified every installation serving web requests as potentially exposed, including PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP, and LiteSpeed.
The disclosure date is not a safe starting point for investigation. Amazon Threat Intelligence says MadPot recorded an exploit attempt on October 17 from an address associated with a commercial anonymization network. It then saw several proof-of-concept implementations around 02:00 UTC on October 21, more attempts from other anonymized infrastructure through 08:00 UTC, and broad in-the-wild use soon after the 14:00 UTC release. Amazon says the early payloads and infrastructure varied, suggesting more than one actor, but it could not establish whether those sensor attempts would have succeeded against ordinary production systems.
Cloudflare provides separate evidence of live pressure. It says its WAF matched attack traffic, watched payloads mutate around controls, and deployed default protections to free and paid WAF customers at 03:02 UTC on October 21. Those observations establish active delivery of exploit-shaped requests. They do not identify every successful victim or make an edge rule a complete fix. The defensible response window begins no later than October 17 for an exposed host, with local evidence deciding whether compromise occurred.
One Flaw Breaks On Out-Of-Memory Cleanup
CVE-2026-109618 concerns how PHP exits some operations after an allocation failure. PHP used longjmp to abort the current context on an out-of-memory condition. In vulnerable paths, request memory could be reachable before it was completely initialized. If allocation failed at that point, shutdown logic could later treat incomplete memory as valid, creating a route from a controlled memory layout to code execution as the web worker account.
Multipart request parsing supplies several ways to reach the dangerous state. The advisory describes requests without a usable declared content length, unbounded headers inside multipart parts, empty file controls that still generate metadata arrays, and nested field names that multiply array work. With Apache mod_php, automatic request-body parsing and the vulnerable shutdown sequence can occur before the target application's code starts. The maintainers validated complete remote code execution over HTTP against normal prefork mod_php configurations.
Deployment details affect reliability, not the need to patch. PHP-FPM terminates a child when startup itself fails, so the advisory does not claim a complete application-independent FPM exploit for this CVE. It does find FPM susceptible to application-specific out-of-memory paths after normal startup. Source review indicates a mod_php-like risk for FrankenPHP, while LSAPI appears closer to FPM and had not received the same full exploit validation at publication. Treat those distinctions as forensic context, not as permission to leave another server API unpatched.
The Second Flaw Carries State Into Another Request
CVE-2026-109619 is a worker-lifecycle failure. PHP keeps global error, session, object, and extension state between requests, but values that point into one request's memory must be cleared before that memory is released. Fatal errors, out-of-memory exits, and even some later diagnostics can leave a pointer behind. A subsequent request that reaches the same persistent worker may use, free, or branch on that stale state before normal initialization replaces it.
A working chain therefore needs a producer, a consumer, and worker reuse. The producer publishes request-owned state and exits without resetting it. The worker frees the request heap but retains the reference. The consumer is an early operation in a later request. The advisory confirms a PHP 8.5 fatal-error-backtrace path for mod_php and a session-upload-progress lifecycle path for both mod_php and PHP-FPM. Session upload progress is enabled by default and can execute before ordinary session initialization, even when application code never calls session_start.
Load balancing across several workers can reduce the probability that a producer and consumer meet, but retries can restore that probability. Worker recycling likewise changes reliability without removing the defect. The confirmed impact includes heap use-after-free, memory disclosure, and remote code execution with worker privileges. The advisory also identifies wider families of error, object, extension, and configuration state whose practical reach depends on the application and server setup, which is why no generic configuration switch closes the entire class.
Patch The Runtime That Actually Serves The Request
Upstream users should move to 8.5.12, 8.4.27, 8.3.36, or 8.2.35. Version 8.2 reaches upstream end of life on December 31, 2026, so that branch needs a migration plan in addition to the immediate fix. PHP 8.1 and older no longer receive ordinary upstream releases. A lower version number can still be safe when a Linux distributor or commercial LTS vendor backports the patches, so compare the installed package against that vendor's advisory instead of relying only on php -v.
Ubuntu's advisory illustrates the distinction. It ships fixed revisions for supported releases and older ESM branches, including 8.1.2-1ubuntu2.28 for Ubuntu 22.04 and 8.3.6-0ubuntu0.24.04.13 for Ubuntu 24.04. Those package revisions do not resemble the upstream fixed numbers because the security changes were applied to distribution-maintained baselines. Container images, hosting panels, appliances, serverless layers, and vendor products that bundle PHP need their own proof of remediation.
After installation, restart every process that loaded the old runtime. Apache modules remain in server processes, PHP-FPM pools keep their workers, and long-running containers do not change when a newer image appears in a registry. Query the binary inside each live container or execution environment, verify the distributor revision where applicable, and confirm that worker start times follow the update. Updating application dependencies, WordPress plugins, or framework code does not repair either PHP memory-lifecycle flaw.
Temporary Controls Buy Time, Not Closure
The PHP advisories are explicit that updating is the only complete mitigation. For CVE-2026-109618, an administrator who cannot patch immediately can set memory_limit=-1 at an administrative level and restart every worker, reducing the predictable per-request out-of-memory trigger. The advisory warns that a lower-level allocation can still fail, so the vulnerable exit remains reachable. It also advises conservative request-size limits and independent frontend bounds on multipart parts, part headers, nested inputs, and uploads.
For CVE-2026-109619, disabling fatal_error_backtraces on PHP 8.5 removes one confirmed producer, while disabling session.upload_progress removes the confirmed early session path. Neither setting covers every source or consumer of stale state. Restricting multipart uploads can break the public trigger used in current exploit traffic, but it can also break legitimate forms and still does not cover all application-specific paths. Apply such controls only as dated containment measures while a fixed runtime is deployed.
WAF rules and isolation are useful layers. Cloudflare says request content alone was not always sufficient to distinguish exploitation from legitimate traffic, so it combined request and origin-response signals. If a system cannot be fixed immediately, remove it from direct internet access, limit upstream reach, narrow the worker account's filesystem and network permissions, and preserve logs before restarting. Do not advertise a filtered but vulnerable host as remediated.
Investigation Must Reach Beyond Web Access Logs
Start the review at October 17 or earlier if local exposure history warrants it. Amazon recommends looking for POST requests containing PHP_SESSION_UPLOAD_PROGRESS in form uploads, unexpected child processes, and file modifications. Those are useful leads, not verdicts. The published IP addresses include shared anonymization infrastructure, and Amazon specifically advises investigation rather than simple blocking. Attackers can change infrastructure, and a successful memory-corruption request may not leave a clean application error.
Correlate reverse-proxy and web-server requests with PHP errors, process creation, outbound connections, new scheduled tasks, modified web roots, altered SSH material, container changes, and cloud identity events. Determine the privilege and secrets available to the web worker, including database credentials, signing keys, object-store tokens, and instance metadata access. If credible post-exploitation evidence exists, isolate the host, preserve volatile and disk evidence, rotate reachable credentials, and rebuild from a known-good image after closing the entry point.
Several facts remain unsettled. Public reporting does not enumerate confirmed victim organizations, the earliest MadPot attempt was not proven successful, and exploit portability depends on server API, build, extensions, allocator layout, application flow, and worker routing. Those unknowns argue for measured language, not delay. The runtime flaws are confirmed, fixed releases exist, and active exploit delivery is documented. Patch coverage and evidence collection can proceed without pretending the public record answers every compromise question.
Checklist
- Inventory every internet-facing and internal PHP runtime, including containers, hosting panels, appliances, cron workers, alternate server APIs, and vendor products that embed PHP.
- Upgrade upstream PHP to 8.5.12, 8.4.27, 8.3.36, or 8.2.35, or verify the exact fixed package revision in the relevant distributor or LTS advisory.
- Restart Apache, PHP-FPM pools, containers, and other persistent workers, then verify the running binary and process start time rather than only the installed package database.
- Where patching is delayed, isolate the service, constrain multipart requests where compatible, apply vendor WAF rules, and treat configuration changes as temporary risk reduction.
- Review evidence from at least October 17 for upload-progress markers, anomalous POST bodies, PHP failures, unexpected processes, file changes, persistence, and outbound connections.
- Map the web worker's accessible credentials and services; rotate secrets and rebuild affected hosts if evidence indicates code execution or post-exploitation activity.
- Record each runtime, fixed version or backport, restart proof, exposure window, and investigation result so application owners cannot close the issue on a CMS or plugin update alone.
Sources
- PHP: critical remote code execution advisory and fixed releases open_in_new
- PHP GitHub Security Advisory: CVE-2026-109618 out-of-memory corruption open_in_new
- PHP GitHub Security Advisory: CVE-2026-109619 stale global state open_in_new
- AWS Security Blog: PHP2Shell exploitation before public disclosure open_in_new
- Cloudflare: php2shell attack traffic and WAF protections open_in_new
- ENISA: joint statement on the critical PHP vulnerabilities open_in_new
- Ubuntu Security Notice USN-8948-1: fixed distribution packages open_in_new
Continue Reading
Node.js Brotli Flaw Makes Compressed Data A Code-Execution Boundary
Node.js fixed a Brotli decoder out-of-bounds write across supported releases. Patch runtimes, rebuild images, and audit untrusted decompression paths.
Zeabur Breach Turns Environment Variables Into A Full Rebuild Problem
Zeabur says attackers read 3.2 million environment-variable records and reached 101 servers as root. Customers need secret rotation, rebuilds, and migration.
Gyazo Breach Turns Image Metadata Into A Long-Lived Privacy Risk
Gyazo's final investigation links unsafe media conversion to database exfiltration, 23.62 million user records, and metadata for deleted images.