PHP CVE-2026-109618 and CVE-2026-109619: early mitigation steps PHP released fixes for CVE-2026-109618 and CVE-2026-109619 in PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35, two memory-handling flaws that can lead to remote code execution without a login and allow attackers to read worker memory holding passwords and API keys. watchTowr's honeypots saw exploitation on 21 October, Cloudflare reported attack traffic against its customers, and Amazon's honeypots logged a first attempt on 17 October, four days before PHP published the fix; the PHP security team said it found no working exploit among the leaked proofs of concept at release. For servers that cannot yet be patched, the guidance is to block multipart requests at the web server, set session.upload_progress.enabled = 0, and on PHP 8.5 set fatal_error_backtraces = 0, though no setting fully prevents either bug. I wrote this post on the morning of 21 October, before PHP released the fix. The fix is out now: PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35. Installing it is the only complete fix. How to apply the patches https://ma.ttias.be/php-cve-2026-109618-patch/ has the steps for each distribution. This page is for servers you cannot patch yet, for example an old PHP without a backported fix. The steps below lower the risk until you can patch. They do not remove it. Most of this post was written with Claude and Codex, and I tested every config in it. Point your LLM at this page, and let it propose the changes for your own servers. What the bugs are what-the-bugs-are - CVE-2026-109618: PHP can run out of memory while it sets up a request. The cleanup afterwards then uses data that was never fully set up. The confirmed ways to make PHP run out of memory are in multipart request parsing. - CVE-2026-109619: state from one request can remain after its memory is freed. A later request on the same PHP worker can then use it. The confirmed cases are the session upload-progress feature, and fatal error backtraces on PHP 8.5. Both can lead to remote code execution without a login. The researchers also showed that an attacker can read parts of the PHP worker’s memory. That memory can hold passwords and API keys php2shell.com https://www.php2shell.com/ . Every PHP that serves web requests is affected: PHP-FPM, Apache with mod php , php-cgi , FrankenPHP and LiteSpeed. PHP rates mod php as the highest risk. Attacks have started. watchTowr’s honeypots saw exploitation on 21 October watchTowr https://watchtowr.com/intelligence/php-cve-2026-109618-faq/ . Cloudflare saw attack traffic against its customers and attackers changing their requests to get past its rules Cloudflare https://blog.cloudflare.com/php-vulnerabilities-waf-protection/ . Amazon saw a first attempt on its honeypots on 17 October, four days before PHP published the fix. It now calls the bug “broadly exploited in the wild”, but does not know whether the early attempts would have worked AWS https://aws.amazon.com/blogs/security/amazon-threat-intelligence-identifies-php2shell-exploitation-prior-to-public-disclosure-in-madpot/ . None of them has named a confirmed break-in. The PHP security team says it inspected the leaked proofs of concept and found no working exploit among them at the time of release PHP Foundation https://thephp.foundation/blog/2026/10/21/todays-php-security-release-and-how-were-strengthening-php-security/ . On 22 October Sansec wrote https://sansec.io/research/php2shell that mass exploitation is now less likely than it expected on release day. It says an attack needs specific knowledge of the target server and specific conditions on it. According to Sansec, a researcher found that the public exploits do not work against a default PHP installation. Most need the application to have a separate file inclusion bug. Sansec still says to update PHP. What actually helps what-actually-helps No setting fully prevents either bug. PHP says so in both advisories. These measures block the paths that PHP has confirmed. Do them in this order: | Measure | Bug | What it blocks | Cost | |---|---|---|---| | Block multipart at the web server block-multipart-requests-at-the-web-server | Both | The out-of-memory paths in multipart parsing, and the upload-progress path. On mod php , normal form posts can also trigger CVE-2026-109618, so use memory limit = -1 there too | File uploads break, except on paths you allow | | session.upload progress.enabled = 0 turn-off-session-upload-progress | CVE-2026-109619 | The confirmed upload-progress path, on mod php and PHP-FPM | Upload progress bars stop working | | fatal error backtraces = 0 php-85-turn-off-fatal-error-backtraces PHP 8.5 only | CVE-2026-109619 | The path behind PHP’s strongest confirmed exploit. It is on by default | Fatal errors no longer include a backtrace | | No PHP settings applied per request remove-php-settings-applied-per-request | CVE-2026-109619 | A warning from such a setting is one of the two confirmed triggers | Move the settings to php.ini or the FPM pool | | pm.max requests = 1 php-fpm-one-request-per-worker PHP-FPM | CVE-2026-109619 | State that one request leaves behind for the next request on the same worker | Slower | | memory limit = -1 remove-the-php-memory-limit | CVE-2026-109618 | The memory limit that attackers make PHP hit, for multipart and normal form posts. The main fix for mod php . Not complete | One request can use all of the server’s memory | | Low post max size and input limits lower-post max size-and-input-limits | CVE-2026-109618 | Makes it harder to push PHP out of memory | Large forms and uploads may fail | | Fix fatal errors attackers can trigger fix-fatal-errors-that-attackers-can-trigger | CVE-2026-109619 | The confirmed PHP-FPM path, which starts with a fatal error in your application | Developer time | None of these covers a fatal error or out-of-memory condition that an attacker can trigger inside your own application. Wiz, one of the reporters, describes https://www.wiz.io/blog/php2shell-php-rce an OPcache path. These measures are not confirmed to cover it. Set every PHP setting in php.ini , the FPM pool or the web server config. Then restart every PHP worker. A reload is not enough. Do not use ini set or .user.ini for any of them PHP’s advisory https://www.php.net/archive/2026.php . If you cannot do any of this, take the site offline until you can patch. Read-only mode make-the-site-read-only blocks most, but not all, confirmed paths. Block multipart requests at the web server block-multipart-requests-at-the-web-server This stops the request before PHP sees it. PHP itself recommends it for apps that do not use multipart advisory https://github.com/php/php-src/security/advisories/GHSA-w8hw-w9fx-j79w . On mod php , this is not enough. Calif, one of the reporters, also triggered CVE-2026-109618 with a normal form post application/x-www-form-urlencoded on Apache with mod php . PHP-FPM is not affected by that path, because it stops the worker when request startup fails Calif https://calif.io/php2shell/ . On mod php , also remove the PHP memory limit remove-the-php-memory-limit . Tested versions: nginx 1.29.8, Apache 2.4.69, lighttpd 1.4.85 and Caddy 2.10.2, on 21 October 2026. Each rule returned 403 for multipart requests, with POST and PUT, in lowercase and uppercase. GET, JSON and application/x-www-form-urlencoded requests still returned 200 . PHP also parses Content-Type: MULTIPART/FORM-DATA in uppercase. So every rule ignores case. nginx: block all multipart nginx-block-all-multipart http {} context, e.g. /etc/nginx/conf.d/block-multipart.conf map $http content type $block multipart { default 0; "~ multipart" 1; } inside every server {} that passes requests to PHP, including default/catch-all servers if $block multipart { return 403; } If an error page 403 sends the request back to PHP, use return 444; instead. nginx: allow multipart only on your upload endpoints nginx-allow-multipart-only-on-your-upload-endpoints map "$http content type|$uri" $block multipart { default 0; "~ multipart. \|/ avatar/upload|livewire/upload-file $" 0; "~ multipart" 1; } Replace the paths with your own upload endpoints. Tested results: /login returned 403. /avatar/upload and /livewire/upload-file returned 200. /avatar/upload?x=1 also returned 200. $uri does not include the query string. /x/avatar/upload/y returned 403. The allowed endpoints stay exposed until you patch. Apache 2.4 apache-24