Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.
Sources: National Vulnerability Database, CISA KEV, Exploit-DB
CVE-2026-104192 Overview
CVE-2026-104192 is a double-free vulnerability [CWE-415] in Dragonfly, an in-memory data store used as a Redis-compatible backend for modern application workloads. The flaw resides in OpaqueObjLoader::CreateStream within src/server/rdb_load.cc. When loading serialized stream groups, the loader can associate a single streamNACK with both a consumer group's global pending entries list (PEL) and a consumer-local PEL, then free the shared object when a duplicate consumer entry is rejected. Subsequent cleanup frees the same object again, corrupting the allocator. Because Dragonfly ships with authentication disabled by default, an unauthenticated adjacent-network client can trigger the condition through a crafted RESTORE command.
Critical Impact
Unauthenticated attackers on an adjacent network can corrupt the allocator through a crafted serialized stream, causing denial of service and potentially arbitrary code execution as the Dragonfly service account.
Affected Products
- Dragonfly in-memory data store versions prior to 1.40
- Default Dragonfly deployments with authentication disabled
- Any application exposing Dragonfly's RESTORE command to untrusted clients
Discovery Timeline
- 2026-10-13 - CVE-2026-104192 published to the National Vulnerability Database
- 2026-10-13 - Last updated in NVD database
Technical Details for CVE-2026-104192
Vulnerability Analysis
Dragonfly implements Redis stream semantics, including consumer groups that track unacknowledged messages via PEL structures. During RDB (Redis Database) deserialization, OpaqueObjLoader::CreateStream walks serialized consumer entries and inserts each pending streamNACK object into both the group-level PEL and the owning consumer's local PEL. The two containers share ownership of the same heap allocation.
When the loader encounters a duplicate consumer name in the serialized payload, it rejects the entry and frees the shared streamNACK. The group PEL still holds a dangling pointer to that freed memory. When the stream is later torn down or additional cleanup runs, the same pointer is freed a second time, producing a classic double-free.
An attacker who can send a single RESTORE command with an attacker-controlled payload can shape the allocator state. This leads to allocator metadata corruption, process crash, and, under favorable conditions, control over subsequent allocations sufficient to achieve code execution as the Dragonfly service account.
Root Cause
The root cause is shared ownership of streamNACK objects between the group PEL and consumer PEL without reference counting or clear ownership transfer. The duplicate-consumer rejection path frees the object while another container still references it, violating single-owner invariants expected by the cleanup code.
Attack Vector
Exploitation requires network reachability to the Dragonfly service. Default installations do not require authentication, so an unauthenticated client on the adjacent network can issue the malicious RESTORE command directly. The attacker supplies a serialized stream payload containing a consumer group with at least one duplicate consumer entry referencing an existing NACK.
// Patch excerpt - src/server/rdb_load.cc
// Fix enforces one-consumer-per-PEL-entry when loading stream groups
}
}
+ uint64_t assigned = 0;
for (const auto& cons : cg.cons_arr) {
streamConsumer* consumer = StreamCreateConsumer(
cgroup, ToSV(cons.name, &buf1_), cons.seen_time, SCC_NO_NOTIFY | SCC_NO_DIRTIFY);
Source: Dragonfly commit 6c6b27a5. The patch introduces an assigned counter and tightens consumer handling so a NACK cannot be bound to multiple PELs or freed while still referenced.
Detection Methods for CVE-2026-104192
Indicators of Compromise
- Unexpected RESTORE commands sent to Dragonfly from unauthenticated clients, especially with large serialized stream payloads
- Dragonfly process crashes, SIGSEGV or SIGABRT events, and malloc or jemalloc corruption messages in service logs
- Core dumps or restarts of the Dragonfly service account shortly after client traffic to port 6379
Detection Strategies
- Monitor Dragonfly command logs for RESTORE operations originating from non-application sources
- Inspect network telemetry for RESP protocol traffic to Dragonfly from unauthorized subnets
- Alert on repeated Dragonfly service restarts or abnormal exit codes consistent with heap corruption
Monitoring Recommendations
- Enable verbose command logging on Dragonfly and forward logs to a centralized analytics platform
- Correlate crash events with preceding client command sequences to identify exploitation attempts
- Track Dragonfly version inventory across hosts and flag any instance running a release prior to 1.40
How to Mitigate CVE-2026-104192
Immediate Actions Required
- Enable authentication on all Dragonfly instances by configuring requirepass or equivalent credential enforcement
- Restrict network access to Dragonfly to trusted application hosts using firewall rules or security groups
- Audit exposed Dragonfly instances for unauthenticated accessibility from untrusted networks and shut down any that are internet-reachable
Patch Information
The upstream fix is available in Dragonfly commit 6c6b27a5 and Pull Request #7929. Additional context is published in GitHub Security Advisory GHSA-cg35-6jf4-crfh. According to the advisory, the source fix has not yet been mapped to a published release. Operators should track the Dragonfly repository for a tagged version that includes the fix and upgrade as soon as it is available.
Workarounds
- Disable or block the RESTORE command through command renaming or ACL restrictions where supported
- Deploy Dragonfly behind a reverse proxy that filters RESP commands from unauthenticated clients
- Place Dragonfly on isolated network segments and require mutual TLS between application tier and the data store
# Example: restrict Dragonfly to loopback and enforce authentication
dragonfly \
--bind=127.0.0.1 \
--requirepass='<strong-random-secret>' \
--port=6379
# Example: iptables rule to allow only application subnet
iptables -A INPUT -p tcp --dport 6379 -s 10.0.10.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 6379 -j DROP
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.
Sources: National Vulnerability Database, CISA KEV, Exploit-DB

