The Redis Port You Forgot Is Listening: Cluster Bus Memory Disclosure (CVE-2026-92925) and How to Find It
Every Redis Cluster node opens a second TCP port — the cluster bus, by default the client port plus 10000, so a node on 6379 is also listening on 16379. Redis states plainly that this protocol "has no authentication of its own." CVE-2026-92925 is an out-of-bounds read in that port's packet parser: a single unauthenticated packet makes a node leak adjacent memory into a field that CLUSTER NODES then serves to any client. We reproduced it against Redis 8.8.3, and confirmed the fix in 8.10.2 rejects the same packet. The bug itself is modest — a bounded read, not code execution — but it is a useful reminder that a port most operators never think about speaks a fully-trusted protocol to anyone who can reach it.

Real reproduction in an isolated cluster. One unauthenticated packet to bus port 16379 makes Redis 8.8.3 return an over-long hostname via CLUSTER NODES — the 32 bytes we supplied, then ~1,800 bytes the parser read past them. This run is an AddressSanitizer build, so those trailing bytes are the sanitizer's own fill pattern: it proves the over-read's distance without exposing real memory. On a plain build the same over-read returns genuine adjacent heap (see below). Patched 8.10.2 drops the packet and leaks nothing.
The Vulnerability
Redis Cluster nodes gossip over the cluster bus for failure detection, configuration updates and failover — a separate binary protocol from the command port. By default the bus port is the data port plus 10000 (6379 → 16379), configurable with cluster-port. What matters for this bug is that, in Redis's own words, "the cluster bus protocol has no authentication of its own": the only thing that authenticates a bus peer is tls-cluster (mutual certificate verification), which is disabled by default. requirepass and ACLs gate the command port only — they do not apply to the bus. Any host that can reach 16379 can speak the protocol.
CVE-2026-92925 is CWE-125 (Out-of-bounds Read) in the parser for PING/PONG/MEET gossip packets. These packets can carry variable-length extensions — among them a hostname and a human-nodename, both strings. Before Redis 8.10.0, clusterProcessPacket validated an extension's 8-byte padding alignment and the packet's total length, but never checked that a string-carrying extension was actually null-terminated:
// src/cluster_legacy.c (Redis < 8.10.0) — the missing check
uint16_t extlen = getPingExtLength(ext);
if (extlen % 8 != 0) { // padding alignment: checked
... return 1;
}
if (totlen > explen + extlen) { // total length: checked
... return 1;
}
// null-termination of a string extension: NOT checkedAn accepted packet's hostname pointer is then handed to updateAnnouncedHostname(), which calls sdscpy(new) → strlen(new). With no terminator, strlen walks past the attacker's bytes through adjacent heap until it happens to hit a zero, and everything it reads is copied into the node's hostname — which is served, verbatim, to any client that runs CLUSTER NODES. The out-of-bounds read becomes a client-visible memory disclosure.
Reproducing It
We stood up an isolated three-node cluster on unmodified Redis 8.8.3, built a raw cluster-bus PING carrying a 32-byte hostname extension with no null terminator, and sent it to a node's bus port. The packet layout comes straight from Redis's own test helpers (build_cluster_bus_ping / build_hostname_extension); the node ID it spoofs is read from CLUSTER MYID, which any client can do without authentication.
# AddressSanitizer 8.8.3: over-read runs ~1,800 bytes past the payload.
# Those bytes are ASan's own fill pattern, so this proves the DISTANCE
# of the read without exposing real memory.
hostname field returned: 1832 bytes ( 32 supplied + ~1800 read past )
# plain (non-sanitizer) 8.8.3: a run leaked 8 bytes of GENUINE heap
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA a6ac7792 <- adjacent bytes, hex,
resembling node-id data
# patched 8.10.2: identical packet rejected
# Received ping packet with missing null terminator in extension type 0
hostname field returned: [empty] — packet dropped, no leakTwo honest limits on the impact, both of which are why this is rated medium and not critical. First, the disclosure is bounded and opportunistic: the read stops at the next zero byte in the heap, so an attacker controls neither how far it runs nor what lands there. On our AddressSanitizer build the read ran ~1,800 bytes into the sanitizer's fill; on a plain build a run leaked 8 bytes of genuine adjacent heap — ASCII a6ac7792, hex that resembles internal node-id data. That variance (8 vs ~1,800 bytes) is the confidentiality characterization: the leak is real but neither steerable nor reliably interesting. Second, it is ephemeral: in a live cluster the genuine node re-gossips a correct hostname within seconds and overwrites the injection. The durable case is impersonating a node that is down — a failure or failover window — or an attacker re-injecting continuously. The underlying over-read, though, fires on any accepted packet regardless. Denial of service is a theoretical ceiling rather than a demonstrated result: we saw no crash, and the receive buffer's doubling allocation tends to keep the read inside the allocation. The CVSS vector reflects all of this: 7.1 (v3.1) / 6.0 (v4.0), AV:A (adjacent), C:L/I:N/A:H — a limited read and potential denial of service, not code execution. The GitHub advisory calls it medium; Red Hat rates it Important. Redis Software and Redis Enterprise are not affected; Valkey is independently affected and fixed separately.
AM I EXPOSED?
- AFFECTEDRedis OSS/CE in cluster mode (cluster-enabled yes) on any release below 8.10.0 — the vulnerable hostname/human-nodename extensions date to Redis 7.0 — where the cluster bus port (default client + 10000, e.g. 16379) is reachable by an untrusted host and tls-cluster is off. The non-obvious part: the null-termination fix landed only in the 8.10 line, so even a fully-updated 8.8.3 (2026-09-17) — which added the startup hardening below but not the code fix — is still code-vulnerable to the over-read. We reproduced on 8.8.3 and confirmed the guard is absent in the 8.2, 8.4, 8.6 and 8.8 branches by reading the source.
- NOT YOUStandalone (non-cluster) Redis — the bus port only exists in cluster mode. Deployments with tls-cluster yes, where an unauthenticated peer cannot complete the handshake. Redis 8.10.0+ for the code fix. Redis Enterprise / Redis Software.
- CHECKOn a node: redis-cli INFO cluster | grep cluster_enabled (:1 means cluster mode, so a bus port exists). From an untrusted host, test whether that bus port is reachable: nc -z -v <node> 16379 — noting this probes only the default port; a custom cluster-port listens elsewhere, so a clean result is not an all-clear.
- FIXMove to the Redis 8.10 line (8.10.2 or later) — that is where the code fix lives; there is no code-fixed 8.8.x, so a deployment that must stay on 8.8 has only the mitigations. Those are: firewall the cluster bus port so only cluster peers can reach it, and/or enable tls-cluster — both remove the unauthenticated reachability the bug depends on.
The Real Story: an Unauthenticated Port Redis Is Now Hardening
The parser bug is the occasion; the standing condition is more interesting. The cluster bus has always trusted anyone who can reach it, and Redis is changing that right now. Alongside the fix, PR #15722 ("Make an unauthenticated cluster bus port an explicit choice," merged 2026-09-15) adds a new option, cluster-bus-port-protected-mode. Read the difference between branches carefully, because it is easy to get backwards:
- • In today's shipped releases (the 2026-09-17 builds), the option exists but defaults to no — the node only warns at startup that its bus port is unauthenticated. It is not a mitigation by default.
- • On the unstable branch — i.e. the next major — the default is yes: a node refuses to start in cluster mode unless tls-cluster is enabled or the operator explicitly opts out. Redis flags this as a breaking change.
So the accurate summary is: Redis has added the switch everywhere and made protected-by-default the behaviour of the next major; in current releases the bus still ships unauthenticated, warning only. That warning line is worth reading — it is Redis telling operators, in the log, that a port they may have exposed speaks a fully-trusted protocol.
Investigation Workflow
Two questions matter for a fleet of self-managed Redis: which hosts run clustered Redis with a reachable bus port, and which of those are below 8.10.0. The first is answerable from the network; the second needs the version, which the command port gives up readily.
1. Port Scan: Find Reachable Cluster Bus Ports
The client port (6379 by default) is the obvious one; the finding here is the bus port beside it (16379, or cluster-port + 10000 for a custom data port). A cluster bus port reachable from anywhere but the other nodes is the exposure — detection rules keyed on a literal 16379 will miss custom cluster-port deployments, so treat "a Redis data port with a second port exactly 10000 above it" as the fingerprint, not the number alone.
2. Confirm Cluster Mode and Read the Version
On the command port, CLUSTER INFO confirms cluster mode and INFO server returns redis_version — the whole finding, since the null-termination fix is present only from 8.10.0. If the instance requires auth on the command port you may not get the version remotely, but the bus port's reachability is the exposure regardless of what the version turns out to be.
3. Cross-Reference Configuration
Reachability plus version establishes exposure; the mitigating factor is tls-cluster. Confirm on the box whether it is enabled — with it on, an unauthenticated peer cannot deliver the malformed packet at all, which downgrades an exposed, unpatched node from "anyone on the segment can hit the bus" to "peers only."
Remediation
- Upgrade to the Redis 8.10 line (8.10.2 or later). This is the code fix: the parser now rejects a string extension with no null terminator instead of reading past it. The latest 8.2–8.8 releases carry the startup hardening but not this fix, so an upgrade to the 8.10 line is what actually closes the read.
- Firewall the cluster bus port. The bus port must be reachable from the other cluster nodes and no one else. This is the single most effective control and it is independent of version — a correctly firewalled bus is not exposed to an untrusted attacker at all.
- Enable tls-cluster. Mutual certificate verification is the only thing that authenticates the bus. With it on, an unauthenticated peer cannot complete the handshake, so it cannot deliver a malformed gossip packet.
- Heed the startup warning. On current releases, a node logs a warning when its bus port is unauthenticated. Treat that line as an action item, not noise; on the next major, that same condition will stop the node from starting.
Triage Notes
- Remote recon proves: that a host runs clustered Redis (CLUSTER INFO), its version (INFO server), and whether the cluster bus port is reachable from your vantage point — so "is this bus exposed and below 8.10.0" is answerable without authenticating to the bus.
- It cannot prove: whether tls-cluster is enabled, whether the bus is firewalled to peers only at the network layer, or whether the over-read has already been used — those are on-box / config checks.
- Evidence to request: the redis_version; cluster-enabled and tls-cluster settings; the firewall policy on the bus port; and the startup log, which warns when the bus is unauthenticated on current releases.
- Escalation threshold: a clustered Redis below 8.10.0 whose bus port is reachable by an untrusted host with tls-cluster off. A firewalled bus, or tls-cluster yes, or 8.10.0+, each drops it to a routine upgrade.
- Finding statement: "The host runs Redis Cluster below 8.10.0 with the cluster bus port (<data port> + 10000) reachable and tls-cluster disabled, exposing it to CVE-2026-92925: an unauthenticated gossip packet with an unterminated hostname extension causes a bounded out-of-bounds read that leaks adjacent heap into the client-visible CLUSTER NODES hostname (CWE-125, CVSS 7.1, memory disclosure / potential DoS — not RCE). Upgrade to 8.10.2+; firewall the bus port to peers only and/or enable tls-cluster as compensating controls."
The network half of this — finding clustered Redis and the second port sitting 10000 above the data port, from your phone — runs in RECON. Confirming tls-cluster and the bus firewall policy are on-box tasks RECON does not replace. Get RECON on the App Store.
Follow @hellorecon for new CVE investigations.
Sources
- → GitHub Advisory GHSA-3gvw-xg56-j2xm (CVE-2026-92925)
- → NVD: CVE-2026-92925
- → redis/redis PR #15263 — the fix (commit 37894fa, src/cluster_legacy.c)
- → redis/redis PR #15722 — cluster-bus-port-protected-mode
- → Red Hat: CVE-2026-92925
- → Redis Cluster documentation — bus port and protocol
- → MITRE: CWE-125 Out-of-bounds Read
This, pointed at the software you run
Every month, every CVE published against the software you run: triaged by hand, in plain words, with the one that deserves attention written up the way these are.
REQUEST PERSONAL BRIEFING →