Introduction: three emergencies in seven days
Between 20 and 27 October 2026, the security community weathered a rare cluster of emergencies. In the space of a single week, three of the internet’s load-bearing components — PHP, the Linux kernel, and Google’s Brotli compression library — each disclosed a critical vulnerability that could hand an unauthenticated, remote attacker code execution. Together they are a case study in how the software the web quietly depends on can fail, and how fast the ecosystem has to move when it does.
This article walks through each of the three disclosures — what the bugs actually are, what they cause, who is exposed, the general and operating-system-specific mitigations, the fixes that eventually shipped, and a technical conclusion on what they have in common.
PHP2Shell: two critical flaws in PHP’s request lifecycle
On 20 October 2026, details of two vulnerabilities in the PHP interpreter leaked ahead of a coordinated disclosure, and the PHP project released emergency fixes the following day at 13:30 UTC. The pair — CVE-2026-109618 and CVE-2026-109619, collectively nicknamed PHP2Shell — each allow unauthenticated remote code execution, rated CVSS v4.0 9.2. Critically, they fire before any application code runs, so application-level authentication cannot block the attack.
What the bugs are
Both flaws share one pattern: a fatal error interrupts PHP partway through an operation, and PHP later treats the incomplete state as valid.
- CVE-2026-109618 (out-of-memory corruption). When PHP converts a form submission into the $_POST array, it stores keys and values in a hash table. During insertion it increments the table’s element counters before allocating the key. If that allocation then exceeds
memory_limit, PHP abandons the insertion — but the counter already includes the new, never-initialised bucket. During shutdown cleanup, PHP walks every counted bucket and interprets the leftover bytes as a live value. An attacker who controls those bytes can steer cleanup into a destructor callback, effectively turning array destruction into asystem()call. - CVE-2026-109619 (stale global state). A PHP worker handles many requests over its lifetime, and some worker-wide fields point at memory that belongs to a single request. If that memory is freed without clearing the fields, a later request follows a stale pointer into freed memory — a use-after-free. PHP confirmed two exploitable paths: fatal-error backtraces (PHP 8.5 only) and upload processing via
session.upload_progress, which is enabled by default and runs even if the application never callssession_start().
What they cause
A successful exploit runs commands with the web server account’s privileges. Datadog Security Labs independently reproduced CVE-2026-109618 with a plain unauthenticated POST request that never reached the application code, ending in a system() call under www-data. Memory disclosure — including reading the PHPSESSID — can also provide the addresses an attacker needs to defeat ASLR. AWS reported exploitation attempts as early as 17 October, four days before public disclosure.
Impact and exposure
Every PHP runtime that serves HTTP is in scope: Apache mod_php, PHP-FPM, php-cgi, FrankenPHP, and LiteSpeed, from PHP 5.4 through 8.5. The affected branches are 8.2 (before 8.2.35), 8.3 (before 8.3.36), 8.4 (before 8.4.27) and 8.5 (before 8.5.12); older, unsupported branches such as 8.1 and 7.4 received source backports from the PHP team.
Mitigations and fixes
Because the flaws sit in PHP itself, the only complete fix is patching. Temporary mitigations reduce but do not remove exposure: for CVE-2026-109618, set memory_limit=-1 at the administrator level and cap request-body size at a reverse proxy or boundary; for CVE-2026-109619, disable session.upload_progress and, on PHP 8.5, fatal_error_backtraces, then restart every worker. On Linux distributions, vendor packages (Debian, Ubuntu, RHEL, Plesk, cPanel) backport the fix; operators on shared hosts should confirm the distributor’s advisory and restart php-fpm or Apache afterwards, as a running worker holds the old runtime until it is replaced. CERT-EU advisory 2026-018 and the CISA alert both recommend isolating internet-facing applications where patching must wait.
MPTCP / Linux kernel: a remote root in the TCP handshake
On 27 October 2026, a use-after-free in the Linux kernel’s IPv4 TCP handshake code was disclosed as CVE-2026-98432. The kernel’s CNA rated it CVSS 9.8; Red Hat rates it 5.9, because exploitation depends on winning a race condition. The nuance matters for the record: the bug is in ordinary IPv4 TCP connection setup, present since Linux 4.4 — Multipath TCP (MPTCP) is merely the path the published proof-of-concept exploit uses.
What the bug is and what it causes
During TCP connection request processing, a race condition can leave the kernel pointing at memory that has already been freed. A remote, unauthenticated attacker who reaches an MPTCP listener can, by sending crafted TCP SYN packets carrying IPv4 Record Route or Timestamp options, trigger the race and, in the published demonstration, execute commands as root. Anthropic’s security researchers, working with an unreleased Claude model, wrote the exploit — the first widely publicised case of a frontier AI model finding its way to remote root.
Impact and mitigation
Because the bug lives in the kernel, a vulnerable server is exposed even if the web application it fronts is fully patched. The recommended stopgap is to prevent the mptcp kernel module from loading, or remove MPTCP listeners; this closes the published exploitation path but is not a substitute for a patched kernel. Real fixes arrive through each distribution’s kernel update or livepatch. As of late October, patched kernels were shipping for Debian, Alpine and several RHEL stream branches, with some distributions — Ubuntu 22.04 among them — still marking their fix as work in progress. The practical guidance: update the kernel, then reboot (or apply a livepatch such as KernelCare), and close any public TCP port running an MPTCP listener.
Broccoli2Shell: one decoder, an enormous blast radius
The third emergency, CVE-2026-111497 (“Broccoli2Shell”, also called Node2Shell and HTTP2Shell), is an out-of-bounds write in Google’s Brotli C decoder, c/dec/decode.c, affecting versions 1.0.3 through 1.2.0 on every platform. Disclosed 21 October 2026, it is the most far-reaching of the three because Brotli is bundled almost everywhere.
What the bug is
The decoder splits a Brotli stream into blocks and switches between block types as it reads them. The function DecodeBlockTypeAndLength() returned a plain boolean, so callers could not tell a malformed stream from one that simply needed more input. On the fast path the return value was ignored entirely: a crafted stream could request a block switch that cannot happen, the decoder treated that as “need more input”, and kept appending attacker bytes to an eight-byte internal buffer, writing past its end and corrupting nearby decoder state. The upstream fix (NVD CVE-2026-111497) returns a hard format error, BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH (-17), instead.
What it causes and who is exposed
A remote attacker who can make an application decompress Brotli data they control can corrupt memory, leak memory contents, crash the process, or — demonstrated by Imperva on unmodified Node.js 24.22.0 — execute arbitrary code. The exposure is extraordinarily wide: Node.js (fixed in 22.23.4, 24.22.1, 26.12.1), Bun, .NET (out-of-band 8.0.33 / 9.0.22 / 10.0.14), Python’s Brotli and brotlicffi PyPI packages, PHP/Java/Ruby/Go bindings, PAN-OS firewalls with TLS decryption and Brotli inspection, Apple operating systems, FFmpeg via JPEG XL, and dozens of projects that vendor their own copy. Notably, HTTP clients decompress Content-Encoding: br responses automatically, so an app can be exposed simply by fetching an attacker-controlled URL.
Mitigations and fixes
The complete fix is updating to Brotli 1.0.10, 1.1.1 or 1.2.1 (or a runtime that bundles a patched copy). Where patching must wait, the interim steps are narrower than for the PHP flaws: for Python, uninstall Brotli and brotlicffi — urllib3/requests/aiohttp fall back to gzip — and reject Content-Encoding: br request bodies at a proxy or WAF. CISA added CVE-2026-111497 to its Known Exploited Vulnerabilities catalogue on 27 October with a 10 November deadline for US federal agencies, underscoring how quickly this one moved from disclosure to active exploitation.
Technical conclusion: memory safety in the shared substrate
Three incidents, three different ecosystems, one common thread. Each was a memory-safety failure — a use-after-free or out-of-bounds write — in code that sits beneath the applications developers actually write, and each was reachable without authentication. PHP2Shell and the MPTCP flaw both punished the moment when an error interrupts an operation and cleanup trusts half-finished state; Broccoli2Shell punished an unchecked return value on a hot decoder path.
The operational lessons are consistent. First, patch early: in all three cases, the only complete fix was the vendor update, and mitigations were stopgaps at best. Second, inventory your dependencies’ dependencies — the Brotli bug spread through vendored copies and automatic HTTP decompression that many teams never realised they had. Third, treat the CISA Known Exploited Vulnerabilities catalogue as the signal it is: all three of these landed on it within days, and deadlines followed fast. For October 2026, the takeaway is simple: if you run PHP, a Linux server, or almost any web runtime, assume you were exposed, and verify the patch actually shipped to the running process — not just the installed package.
