CVE-2026-14587
CVE-2026-14587 is a pre-authentication denial-of-service in Neo4j's Bolt protocol handshake decoder. The vulnerability isn't a flashy remote code execution—it's a resource exhaustion primitive that works because of a design choice in how the decoder handles ambiguous input. When the Bolt handshake parser encounters bytes that could represent either an incomplete message or a malformed message, it defaults to 'wait for more bytes.' This leniency makes sense in development—real networks drop packets and buffers refill—but it becomes dangerous when the input is specifically crafted to never resolve. The trigger is 32 continuation bytes in the capability mask: this should be rejected as malformed, but instead the decoder resets its read index and waits. Those same 32 bytes remain at the buffer's front, so the decoder behaves identically on each attempt. The handshake never completes, the connection stays open, and the server accumulates stuck connections. What matters operationally is that this is pre-authentication. Any client that can reach the Bolt connector—default port 7687—can trigger the condition without credentials. The CVSS 5.5 (Medium) may underestimate the real impact in high-throughput environments. Most Neo4j drivers enforce 30-second socket timeouts by default, meaning individual connections eventually die, but the attack works by outpacing that reclamation: an attacker creating connections faster than the timeout releases them exhausts the connection pool and blocks legitimate traffic. Your exposure depends on the ratio between connection creation rate and timeout reclamation, plus whether your application pools connections in a way that accounts for pathological states. For defenders, check your Bolt listener exposure—Neo4j instances are often internet-adjacent in data pipelines and applications. Review connection pool sizing in your driver configuration; smaller pools with aggressive timeouts limit how much damage a single attacker can inflict. Monitor for handshake incomplete states in connection logs. The fix addresses this specific trigger (32 continuation bytes), but the underlying architectural pattern—decoder state that waits on ambiguous input—may exist in other message types. If the decoder wasn't refactored to deterministically distinguish malformed from incomplete at parse time, treat this as a vulnerability class, not an isolated patch.
Reviewed through automated stages and approved by a human before publication.