October 24, 2026
The Brotli Bug CVE-2026-111497, Explained
How an invalid block switch led to memory corruption, and what the patch changes.

By SAHIL SHARMA
3 min read
How an invalid block switch led to memory corruption, and what the patch changes.
Brotli's decoder decompresses data: it takes a compressed stream and reconstructs its original contents. When input arrives in pieces, the decoder has to decide whether it can continue, needs more bytes, or must reject the stream.
CVE-2026-111497 is a memory-safety flaw in Brotli's decoder, including the copy bundled with Node.js. The Node.js security advisory describes its impact.
Understanding the mistake starts with the difference between incomplete and invalid input.
Waiting for input is a normal part of streaming
Imagine reading a message that arrives over several deliveries. If the first delivery ends halfway through a sentence, waiting for the next one makes sense. A streaming decoder needs a similar way to pause without rejecting valid data.
But some input already breaks the format's rules. Waiting for another delivery cannot make that condition valid. The decoder must report the failure so processing stops.
Those outcomes need different signals because the surrounding code takes different actions in response. A temporary status invites another attempt; a format error ends that decoding operation.
How the wrong signal reached a buffer
A buffer is a reserved area of memory. This decoder used an internal buffer with room for eight bytes. Its size mattered because continued input had to stay within that space.
An invalid block switch took the path associated with missing input. The streaming decoder kept appending bytes, eventually allowing an out-of-bounds write. That means writing into memory beyond the space reserved for the buffer. Node.js documents this sequence in its advisory.
Picture an eight-slot receiving tray. A clerk sees an invalid delivery instruction but reports "send the rest" instead of rejecting it. More items arrive even though continuing is unsafe.
What the patch changes
The upstream Brotli patch changes the block-decoding routine from a boolean result to a result that can express distinct outcomes.
Previously, a false result could represent either insufficient input or an invalid block switch. Calling code could interpret that failure as a reason to request more input. The distinction had been lost before the code responsible for continuing or stopping could use it.
After the fix, an invalid block switch returns BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH. An incomplete read can still return BROTLI_DECODER_NEEDS_MORE_INPUT, and success returns BROTLI_DECODER_SUCCESS.
The patch also passes those results through the surrounding decoding functions. Recognizing an error locally is only useful if the caller receives it and takes the correct path. Here, malformed input reaches a format-error outcome and decoding stops. The changes to the return values and their callers are visible in the patch.
Who needs to act
The relevant prerequisite is attacker-controlled Brotli data reaching a vulnerable decoder. Node.js identifies applications decompressing such data through node:zlib. Possible consequences include a crash, disclosure of process memory, or code execution. Which consequence is reachable depends on the application and its environment. See the advisory's impact description.
Start by finding where your application decompresses external data, including dependency code. Determine which runtime or bundled library performs that operation.
Update the deployed component
Node.js shipped fixes in 22.23.4, 24.22.1, and 26.12.1. Install the appropriate supported patched release or a newer applicable release. The official advisory links those releases.
For other consumers, upstream Brotli fixes are available in 1.0.10, 1.1.1, and 1.2.1. Follow the guidance for the product bundling Brotli; a distribution may backport the fix under a different version string.
Rebuild affected container images or bundled binaries, redeploy them, and verify the replacement processes use the patched component. Updating a development machine leaves existing deployments untouched.
For code review, trace what happens after a parser returns an error. Check that a permanent failure survives every wrapper and cannot become an instruction to retry with more input.
Diagrams are conceptual illustrations created with AI assistance. Technical explanations follow the linked maintainer advisory and upstream patch.
I share more engineering explainers on X (Twitter). You can also connect with me on LinkedIn.