CVE-2026-111497: How to Patch PHP Windows Brotli RCE Flaw

SOC Briefing Summary :: Executive Key Takeaways
- [01]Threat summary: PHP rebuilds official Windows packages for branches 8.2 through 8.5 to fix a critical CVSS 9.2 memory corruption flaw (CVE-2026-111497) in the bundled Brotli compression library.
- [02]Root cause vector: Vulnerable Brotli 1.2.0 decompressor triggered when PHP cURL or Guzzle processes automatically unpack crafted compressed HTTP responses.
- [03]Immediate action: Upgrade to rebuilt Windows packages (numbered *-1), or temporarily disable automatic response decompression in HTTP clients (decode_content => false).
Executive Summary
Just five days after releasing emergency patches for the twin PHP2Shell vulnerabilities, the PHP development team issued an unscheduled rebuild of all official Windows binaries across PHP 8.2, 8.3, 8.4, and 8.5. The emergency rebuild addresses CVE-2026-111497, a critical memory corruption flaw in the bundled Google Brotli compression library rated CVSS 4.0: 9.2 (Critical) by Google and CVSS 3.1: 8.1 by Red Hat.
The vulnerability resides within Brotli 1.2.0 decompressor routines bundled into Windows distributions. An adversary can trigger the flaw remotely when a PHP web application or worker process makes an outbound HTTP request to an untrusted upstream service using PHP's cURL extension or popular HTTP client libraries like Guzzle. If the server responds with a maliciously crafted, compressed Brotli stream, the decompression engine triggers out-of-bounds memory corruption within the php.exe process, opening a path to denial of service or arbitrary code execution.
---
Technical Vulnerability Analysis & Attack Chain

Root-Cause & Exploitation Mechanics
The root cause of CVE-2026-111497 lies in memory allocation and ring-buffer boundary parsing within the Brotli decompressor prior to version 1.2.1. When decompressing a specially structured data stream with malformed distance codes and block length descriptors, Brotli writes past allocated memory bounds on the heap.
The exploitation flow operates through standard PHP HTTP client workflows:
- Automatic Decompression Trigger:
In standard PHP cURL usage, automatic response decompression is disabled by default. However, developers enable it by setting CURLOPT_ENCODING to an empty string (""), which instructs cURL to announce support for all bundled compression formats (Accept-Encoding: gzip, deflate, br).
- The Guzzle Exposure Vector:
Enterprise PHP applications overwhelmingly utilize Guzzle as their primary HTTP client. In Guzzle versions 7.16.1, 8.3.1, and preceding lines, the default configuration sets decode_content => true. Under the hood, Guzzle translates this directly into CURLOPT_ENCODING = "". As a result, virtually all standard Guzzle outbound requests advertise Brotli support automatically.
- Malicious Response Injection:
When the PHP application contacts an external API, webhook destination, RSS feed, or web page, an adversary controlling the destination server (or positioning as a Man-in-the-Middle) returns an HTTP response with header:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Encoding: br
Content-Length: 1042
[Malicious Brotli-compressed byte stream]- Heap Corruption & Code Execution:
As cURL invokes the bundled Brotli 1.2.0 decompressor on Windows, the parser expands the payload into an undersized buffer. Researchers at OpenAI (who discovered the vulnerability) and Imperva demonstrated that repeated execution against Windows binaries can achieve controlled instruction pointer hijacking and shellcode execution under the privileges of the executing PHP worker process (IIS AppPool, FastCGI service, or CLI task runner).
---
MITRE ATT&CK Tactics, Techniques & Procedures (TTPs)
| Tactic | Technique ID | Technique Name | Operational Context |
|---|---|---|---|
| Initial Access | T1190 | Exploit Public-Facing Application | Triggering memory corruption via outbound API requests to adversarial upstream endpoints |
| Execution | T1203 | Exploitation for Client Execution | Exploitation of bundled Brotli decompression routine in php.exe runtime |
| Defense Evasion | T1027.002 | Encrypted/Compressed Payloads | Concealing memory corruption payload inside validly formatted Brotli data stream |
| Impact | T1499.004 | Application or System Exploitation | Crashing PHP FastCGI worker pools to induce widespread Denial of Service |
---
Threat Actor Profile & Campaign Attribution
The vulnerability was discovered and responsibly disclosed by AI safety and security researchers at OpenAI. While no active weaponization was recorded in CISA's Known Exploited Vulnerabilities (KEV) catalog at the time of publication, public exploit research from Imperva on similar Node.js Brotli builds demonstrated that memory corruption can be converted into reliable execution primitives.
Because the underlying PHP core code did not increment version numbers, standard automated version checks like php -v report identical version strings before and after the fix. Defenders must explicitly verify the package build number suffix (-1) and Software Bill of Materials (SBOM) to confirm remediation.
---
Detection & SOC Mitigation Playbook
1. Concrete Remediation & Workarounds
Deploy the following engineering controls across all Windows server environments running PHP:
- Step 1: Install Official Rebuilt Packages:
Download and install the updated Windows zip packages from the official PHP Windows downloads page. Verified build numbers containing Brotli 1.2.1:
- PHP 8.5.12-1 (
php-8.5.12-1-nts-Win32-vs17-x64.zip) - PHP 8.4.27-1 (
php-8.4.27-1-nts-Win32-vs17-x64.zip) - PHP 8.3.36-1 (
php-8.3.36-1-nts-Win32-vs17-x64.zip) - PHP 8.2.35-1 (
php-8.2.35-1-nts-Win32-vs17-x64.zip)
- Step 2: Temporary Guzzle Client Workaround:
If binaries cannot be immediately updated, disable automatic decompression across all Guzzle client instantiations:
use GuzzleHttp\Client;
$client = new Client([
// Explicitly disable automatic decoding of Brotli/gzip responses
'decode_content' => false,
'timeout' => 5.0,
]);- Step 3: Native cURL Workaround:
Ensure native cURL calls do not specify CURLOPT_ENCODING with an empty string or include br:
// DO NOT USE: curl_setopt($ch, CURLOPT_ENCODING, "");
// INSTEAD SPECIFY:
curl_setopt($ch, CURLOPT_ENCODING, "gzip, deflate");2. Network & Perimeter Defenses
- Egress Proxy Inspection: Configure outbound corporate proxies and web application firewalls to strip or rewrite
Accept-Encodingheaders that containbron outbound requests originating from internal PHP application servers. - Inspect Response Headers: Temporarily block inbound HTTP responses with
Content-Encoding: brdestined for internal application tiers that have not completed package upgrades.
3. Endpoint Detection & Hunting Query
Sigma Rule: PHP Process Abnormal Termination on Windows
title: Potential Brotli Memory Corruption Crash in PHP Process
id: c4f8102a-9281-4e78-98e1-bc0192847291
status: experimental
description: Detects sudden crashes or unhandled access violations (0xC0000005) in php.exe processes indicative of Brotli heap corruption exploitation.
references:
- https://thehackernews.com/2026/10/php-issues-second-windows-security.html?ref=cybernewsai.com
author: CyberNewsAI Threat Research Team
logsource:
category: application
product: windows
detection:
selection_event:
EventID: 1000 # Application Error
selection_process:
AppName|contains:
- 'php.exe'
- 'php-cgi.exe'
selection_exception:
ExceptionCode:
- '0xc0000005' # ACCESS_VIOLATION
- '0xc0000374' # HEAP_CORRUPTION
condition: selection_event and selection_process and selection_exception
falsepositives:
- Unrelated PHP syntax or third-party native extension crashes
level: high
tags:
- attack.execution
- attack.t1203Microsoft Sentinel / Defender Hunting Query (KQL)
// Hunt for PHP application crash events and abnormal outbound HTTP traffic patterns
DeviceEvents
| where ActionType == "AppCrash"
| where FileName in~ ("php.exe", "php-cgi.exe")
| extend AdditionalFields = parse_json(AdditionalFields)
| where AdditionalFields.ExceptionCode in ("0xc0000005", "0xc0000374")
| project TimeGenerated, DeviceName, FileName, ProcessCommandLine, AdditionalFields.ExceptionCode, AdditionalFields.FaultingModuleName
| order by TimeGenerated desc---
| Indicator Type | Value | Context |
|---|---|---|
| Vulnerable Component | Brotli 1.2.0 | Vulnerable decompressor bundled in pre-rebuild Windows PHP binaries |
| Vulnerable Package | php-8.5.12-nts-Win32-vs17-x64.zip | Original October 21 release build |
| Vulnerable Package | php-8.4.27-nts-Win32-vs17-x64.zip | Original October 21 release build |
| Vulnerable Package | php-8.3.36-nts-Win32-vs17-x64.zip | Original October 21 release build |
| Vulnerable Package | php-8.2.35-nts-Win32-vs17-x64.zip | Original October 21 release build |
| Patched Version | Brotli 1.2.1 | Fixed library version included in rebuild packages (-1) |
Brotli 1.2.0 (Bundled in PHP Windows x64 NTS/TS)php-8.5.12-nts-Win32-vs17-x64 (pre-rebuild)php-8.4.27-nts-Win32-vs17-x64 (pre-rebuild)php-8.3.36-nts-Win32-vs17-x64 (pre-rebuild)php-8.2.35-nts-Win32-vs17-x64 (pre-rebuild)// VERIFIED_SOURCES_&_REFERENCES
Watch Full Video Briefings on YouTube
Subscribe to CyberNewsAI on YouTube for animated threat vectors, CISO breakdowns, and security briefings.
Related Threat Intelligence
View Archive
Magento CMS Skimmer: How to Detect & Block 953-Store Attack
Over 953 Magento e-commerce stores infected with scanner-evading JavaScript skimmers via cms_block poisoning and PolyShell RCE. Here is how to defend.

CVE-2026-110264: How to Detect & Patch GitLab 10.0 Regex RCE
GitLab patches maximum-severity CVSS 10.0 flaw CVE-2026-110264 allowing unauthenticated RCE across 12 years of releases. Here is how to defend.

Operation FlashHole: How to Detect Lazarus CrossWeb EX Abuse
Lazarus Group launches Operation FlashHole, weaponizing mandatory CrossWeb EX software in South Korea with TechHub loaders. Here is how to defend.