CVE-2026-109618·PHP vulnerability
PHP uses longjmp() for out-of-memory (OOM) errors to exit the current context and abort handling of the request. Some contexts may not properly account for this scenario and leave request memory in an uninitialized state before performing an allocation. The subsequent request cleanup procedure may read or branch on this memory. Multiple OOM strategies can consistently trigger this condition and lead to remote code execution (RCE).
- Severity
- critical
- Software
- PHP
- Fixed in
- 8.2.35 / 8.3.36 / 8.4.27 / 8.5.12 (per branch; PHP 8.1 and older are end-of-life, no official fix)
- Published
Affected versions
Until: 8.2.35-1~deb12u1
Fixed in: 8.2.35 / 8.3.36 / 8.4.27 / 8.5.12 (per branch; PHP 8.1 and older are end-of-life, no official fix)
How to fix this CVE
Update to the patched release for your branch — PHP 8.2.35, 8.3.36, 8.4.27 or 8.5.12 — which is the only complete fix. php.net is explicit: "there are no complete mitigations, updating is the only safe choice." If you genuinely cannot update yet, the documented partial mitigation for THIS CVE is to set memory_limit=-1 in a way applications cannot override — php_admin_value in the FPM pool or in the Apache configuration — and verify that no pool, directory or application re-sets it; configure your OOM policy to kill only the affected worker. Do NOT substitute RLIMIT_AS or RLIMIT_DATA: they can cause the vulnerable allocation failure. This reduces exposure but does not make the installation safe. Once you have patched, set memory_limit back to a real value: the patched PHP enforces a hard upper memory limit that terminates a worker without running shutdown functions, so leaving it unlimited is itself a hazard. For versions with no official patch (PHP 5.4–8.1 are end-of-life), a community stopgap exists: Hosted Power's hp_uploadprogress_guard PHP extension (MIT, linked under References), which since v3 carries PHP's fixed multipart parser per branch behind a memory-headroom guard, mirrors the rest of the official fix component by component, and steps aside on a patched engine (8.2.35 / 8.3.36 / 8.4.27 / 8.5.12 and newer) while keeping its non-php2shell fixes active. Since v3.2.0 it also isolates unserialize() re-entrancy (php-src#24481, still open upstream) and since v3.2.1 it carries PHP's approved fix for the SimpleXML crash that 8.4.27 and 8.5.12 introduced (php-src#24488). It covers PHP 5.4 through 8.5, which makes it the only route for end-of-life branches. Checked against the repository on 22 Oct 2026 (v3.2.2). It is a stopgap, not a replacement for upgrading. Note on the fixed releases, verified against php-src on 22 Oct 2026. Upgrading closes this CVE, but two distinct PHP bugs outlive it. php-src#24481 - a use-after-free in var_destroy() during unserialize() re-entrancy - is still OPEN and confirmed present in 8.5.12, 8.4.27, 8.3.36, 8.2.35 and 7.4.33, and it is reachable over HTTP through the same session machinery this CVE abuses (session.serialize_handler=php_serialize alongside upload-progress tracking), so the fixed release does not by itself close the session attack surface. php-src#24488 - a GC double-free of the SimpleXMLElement properties table that aborts the FPM worker on any request JSON-encoding a SimpleXMLElement caught in a collected cycle - was INTRODUCED by 8.4.27 and 8.5.12 (8.4.26 is unaffected); its fix landed in the PHP-8.4, PHP-8.5 and PHP-8.6 branches on 22 Oct 2026 but has not shipped in a release yet. Patch regardless: this CVE is remote code execution and a worker crash is not. Then track both issues.
sudo apk update && sudo apk upgrade php82 php82-fpm (adjust the package prefix to your PHP version), then restart the service: sudo rc-service php-fpm82 restart. Alpine's edge/community tree tracks upstream closely; on a pinned release branch confirm the patched version has been backported before relying on apk upgrade.What an exploitation attempt looks like
Sample log line indicative of exploitation attempts:
CVE-2026-109618 has no distinctive payload string to match — it is triggered by driving PHP out of memory WHILE it parses a multipart/form-data request body, so request cleanup then runs on half-initialised internal state. The observable fingerprint is a multipart/form-data POST to a PHP endpoint immediately followed by PHP memory-limit errors ("Allowed memory size … exhausted"), repeated HTTP 500s, or a PHP-FPM worker crash/restart — not a specific field or filename. (The PHP_SESSION_UPLOAD_PROGRESS field and weaponised filenames belong to the companion bug CVE-2026-109619.) A standard access log shows only the POST; the memory/worker symptoms are the tell.WAF mitigation (if patching is not yet possible)
Add this rule to your WAF to block exploitation attempts while you schedule the patch.
A WAF cannot reliably stop CVE-2026-109618. There is no distinctive payload to key on — the trigger is memory exhaustion during multipart parsing — and denying all multipart/form-data would break every upload form. The documented control for THIS bug is php.net's own mitigation: set memory_limit=-1 in a way applications cannot override (php_admin_value in the FPM pool or in the Apache configuration), with no pool, directory or application putting a finite limit back; then REVERT it to a real value once you have patched, because the patched PHP enforces a hard upper limit that terminates a worker without running shutdown functions. Patching is the only complete fix.
Note: Defensia's agent ModSecurity rule (id 9910015) targets the upload-progress path of the COMPANION bug CVE-2026-109619 — it does not catch this OOM path. On nginx + php-fpm the request body is not visible to a log-based engine; php-fpm is itself exploitable, so nginx is not a safe harbour.How to check if you are affected
- Confirm your PHP version and branch: php -v (and for each FPM pool: php-fpm8.x -v). Anything 5.4.0–8.5.x before the release-day fix (8.2.35 / 8.3.36 / 8.4.27 / 8.5.12) is affected.
- Check your memory-limit policy: php -i | grep -i memory_limit. php.net's stopgap for this CVE is memory_limit=-1 set un-overridably (php_admin_value in the FPM pool or Apache config), with nothing re-imposing a finite limit — and revert it to a real value once patched.
- Correlate multipart POSTs with resource symptoms: check the PHP-FPM error log and dmesg for "Allowed memory size … exhausted" / out-of-memory / worker "child exited on signal" entries that line up with bursts of multipart/form-data POSTs to PHP endpoints.
- Watch for unexplained PHP-FPM worker churn (workers recycling with no obvious cause) and repeated HTTP 500s from a single endpoint.
- Check for post-exploitation: the web user (www-data, apache, php-fpm) spawning sh/bash/curl/wget, or new or modified PHP files under the web root since release day.
Indicators of compromise
- Session files under session.save_path (default /var/lib/php/sessions) whose contents include '<?php', '<?=', or a serialized object marker 'O:<n>:'.
- Multipart POST requests carrying a PHP_SESSION_UPLOAD_PROGRESS field together with a PHPSESSID supplied in the body rather than a cookie.
- Upload filenames containing PHP open tags or a pipe followed by a serialized object, e.g. |O:4:"Evil":...
- Web user (www-data, nginx, apache, php-fpm) spawning a shell or outbound downloader (sh, bash, curl, wget, python) shortly after a multipart POST.
- New PHP files or webshells appearing under the document root, or unexpected modifications to existing PHP files, dated to release day or later.
- Multipart/form-data POSTs immediately followed by PHP memory-limit errors or repeated HTTP 500 responses from the same endpoint (Wiz).
- Unexpectedly large or malformed PHPSESSID response cookies.
- Unexplained PHP-FPM worker churn — workers recycling or restarting with no obvious cause.
FAQ
Am I affected if my application never handles file uploads?
Yes. The bug is in PHP core and is reached while PHP parses the request body (multipart/form-data) before any application code runs, so you do not need to implement uploads. Any PHP 5.4 through 8.5 install is in scope until patched.
Which versions fix it, and what if I am on an older branch?
Fixed in PHP 8.2.35, 8.3.36, 8.4.27 and 8.5.12 — update to the patched release for your branch. PHP 8.1 and older are end-of-life and get no official fix; Debian/Sury backports 7.4/8.0/8.1, but 5.4–7.3 will never be patched and must be migrated.
I cannot update right now. What is the official stopgap for THIS CVE?
php.net's documented partial mitigation for CVE-2026-109618 is to set memory_limit=-1 in a way applications cannot override (php_admin_value in the FPM pool or in the Apache config), verify nothing re-sets it per pool/directory/app, and configure your OOM policy to kill only the affected worker. Do NOT substitute RLIMIT_AS or RLIMIT_DATA — they can cause the vulnerable allocation failure. It reduces exposure but is not a fix.
Does disabling session.upload_progress help for this one?
That is the official lever for the companion bug CVE-2026-109619, not for this one — CVE-2026-109618 is mitigated by memory_limit=-1. Apply both mitigations if you run the risk, but neither is complete: php.net states plainly that updating is the only safe choice.
How do I tell if someone is trying to exploit it?
Watch for PHP-FPM/worker crashes and segfaults (FPM error log, dmesg: "child exited on signal 11") correlated with bursts of multipart/form-data POSTs to PHP endpoints, for new or modified PHP files under the web root, and for the web user (www-data, apache, php-fpm) spawning a shell or an outbound downloader. See the detection steps above for exact commands.
Related PHP CVEs
References
Track CVEs across your fleet automatically
Defensia scans your Linux servers and tells you exactly which ones are running vulnerable versions — including CVE-2026-109618. Free for 1 server.
Get started free