A critical vulnerability in Predis, one of the two dominant Redis and Valkey clients for PHP, was assigned CVE-2026-84372 on September 1 and carries a CVSS score of 9.8. The short version for anyone deciding what to do this morning: if your application uses Predis 3.0 through 3.2 to talk to a Redis Cluster or a replicated setup, and any user-influenced value ends up as a cache key or argument, an attacker can smuggle extra Redis commands into your data store. If you are on Predis 1.x or 2.x, or you use a single-node connection, this one does not touch you.
That precision matters, because a bare "9.8 in Predis" headline will frighten a lot of teams who are not actually exposed and let the narrow group who are exposed skim past it. The flaw lives only in the aggregate connection code that Predis 3.x uses for clusters and replication. Read on for exactly who needs to move and why the timeline on this one is unusual.
The strange part: the fix shipped nine months before the CVE
The patch is not new. The maintainers corrected this in a commit on August 13, 2025, and it went out in Predis 3.3.0 on November 24, 2025. The public security advisory (GHSA-w6f5-v2h6-g786) did not appear until August 21, 2026, and the CVE record followed on September 1. So the code was quietly safe for anyone who kept up with releases, and the formal warning arrived nearly a year later.
The practical consequence of that gap is a lockfile problem, not a scramble to find a patch. Anyone who upgraded to 3.3.0 or later at any point in the last nine months is already protected and probably does not know this CVE applies to their old builds. Anyone pinned to a 3.0, 3.1, or 3.2 release in composer.lock is still exposed, and now there is a public advisory pointing directly at the weakness. The advisory going public is the event that changes your risk, not the code change that already happened.
What the flaw actually does
Predis lets you batch commands with pipeline(). On cluster and replication connections, the 3.x rewrite of that path took an already-serialized protocol buffer and split it back apart on carriage-return and line-feed boundaries instead of trusting the length prefixes that the Redis wire protocol (RESP) puts in front of every value. A key or value that itself contains those line-break bytes then gets read as if it were additional commands. The Predis maintainer Till Kruss credits the report to a researcher using the handle s2x.
The impact splits by connection type. On a cluster connection, injected commands can be routed and run, which the advisory describes as allowing shard-wide cache deletion, targeted changes or reads of other keys, and node disruption. On a replication connection, the malformed re-parsing throws an uncaught exception that repeatedly kills the affected request, a reliable denial of service. Only the pipeline() path reaches this code. Transactions built with transaction() or a raw MULTI are not affected, and single-node connections never hit the aggregate write path at all.
To be clear about what this is not: there is no report of exploitation in the wild, it is not on CISAs Known Exploited Vulnerabilities list, and no weaponized proof-of-concept is circulating beyond the fix commit and the issue thread that document the root cause. The severity comes from the preconditions being common in real applications, not from active abuse. Cache keys built from URL slugs, usernames, search terms, or other request data are everywhere, and that is exactly the attacker-controlled input the flaw needs.
Check your version, then check your data flow
Two questions settle your exposure. First, which Predis are you on? Run a dependency check and read composer.lock, not composer.json, because the lockfile is what actually ships. If it pins predis/predis between 3.0.0-RC1 and 3.2.0, you are in range. Second, do you connect to a Redis Cluster or a replicated topology, and does any request-controlled value become a key or argument inside a pipeline() call? If both are true, treat this as todays work.
The fix is a version bump. Install predis/predis at release 3.3.0 or newer, which swaps the fragile secondary parser for real command objects so nothing gets re-split on line breaks. If you cannot upgrade immediately, the interim options are narrow but real: stop routing untrusted input into pipelined keys and values on aggregate connections, or move those specific operations off pipeline() until you can patch. Because there is no clean signature for this in most logs, do not count on catching it after the fact. Getting onto a fixed release is the control that matters.
The wider lesson is about how you learn a dependency became dangerous. A silent fix in a changelog is not a notification, and a CVE that lands most of a year after the patch is a reminder that your build is only as current as your lockfile. Teams that pin aggressively for stability get bitten by exactly this pattern: the project moved on, the advisory caught up, and the pinned build stayed frozen at the vulnerable version. A periodic audit of pinned dependencies against fresh advisories closes that gap better than reacting to each CVE as it drops.