jinchengyang98 opened a new issue, #3493:
URL: https://github.com/apache/kvrocks/issues/3493

   # [Security] RESP Protocol Injection via Lua `redis.error_reply()` in kvrocks
   
   ## Summary
   
   kvrocks converts `redis.error_reply()` results from Lua to Redis protocol 
without sanitizing embedded `\r\n` sequences. This allows an authenticated user 
to inject arbitrary RESP messages into the response stream via crafted error 
strings, potentially corrupting subsequent command responses in a shared 
connection pool.
   
   ## Vulnerability Details
   
   - **Affected code**: `src/storage/scripting.cc` — `ReplyToRedisReply()` 
(lines 1293–1300)
   - **Vulnerability type**: RESP Protocol Injection (CWE-116 — Improper 
Encoding or Escaping of Output)
   - **Related CVE**: CVE-2025-67733 (same class in Valkey/Redis)
   
   ## Root Cause
   
   In `ReplyToRedisReply()`, when Lua returns a table with an `err` field 
(i.e., from `redis.error_reply()`), the error string is passed directly to 
`redis::Error()` without sanitizing embedded `\r\n`:
   
   ```cpp
   // src/storage/scripting.cc line 1297-1300
   if (t == LUA_TSTRING) {
     output = redis::Error({Status::RedisErrorNoPrefix, lua_tostring(lua, -1)});
     lua_pop(lua, 1);
     return output;
   }
   ```
   
   `redis::Error()` constructs a RESP error reply by concatenation:
   ```cpp
   // src/server/redis_reply.cc line 49
   std::string Error(const Status &s) { return RESP_PREFIX_ERROR + 
StatusToRedisErrorMsg(s) + CRLF; }
   ```
   
   With `Status::RedisErrorNoPrefix`, `StatusToRedisErrorMsg()` returns the raw 
message string. If the message contains `\r\n`, the RESP output includes 
embedded delimiters, splitting the response into multiple messages:
   
   **Attack input:**
   ```lua
   return redis.error_reply("ERR injected\r\n+INJECTED_SIMPLE_STRING\r\n")
   ```
   
   **Wire output:**
   ```
   -ERR injected\r\n+INJECTED_SIMPLE_STRING\r\n\r\n
   ```
   
   A RESP client parses this as:
   1. `-ERR injected` → error reply
   2. `+INJECTED_SIMPLE_STRING` → simple string reply (injected)
   3. `\r\n` → (spurious)
   
   ## Attack Scenario
   
   1. An authenticated client with access to `EVAL` or `FCALL` sends:
      ```
      EVAL "return redis.error_reply('ERR x\r\n+PONG\r\n')" 0
      ```
   2. The server responds with:
      ```
      -ERR x
      +PONG
      
      ```
   3. If the connection is part of a connection pool, the injected `+PONG` is 
consumed as the response to the next pooled command (e.g., if a pool `PING` 
follows), causing response desynchronization.
   
   ## Affected Code
   
   ```cpp
   // src/storage/scripting.cc (kvrocks HEAD 9c411259, 2026-05-17)
   // Line 1297-1300: error_reply field handling
   if (t == LUA_TSTRING) {
     output = redis::Error({Status::RedisErrorNoPrefix, lua_tostring(lua, 
-1)});  // <-- unsanitized
     lua_pop(lua, 1);
     return output;
   }
   ```
   
   ## Suggested Fix
   
   Strip `\r\n` from the error string before constructing the RESP error reply:
   
   ```cpp
   if (t == LUA_TSTRING) {
     std::string err_msg = lua_tostring(lua, -1);
     // Strip embedded CRLF to prevent RESP protocol injection
     err_msg.erase(std::remove_if(err_msg.begin(), err_msg.end(),
                                  [](char c){ return c == '\r' || c == '\n'; }),
                   err_msg.end());
     output = redis::Error({Status::RedisErrorNoPrefix, err_msg});
     lua_pop(lua, 1);
     return output;
   }
   ```
   
   Or add sanitization in `redis::Error()` / `StatusToRedisErrorMsg()` for the 
`RedisErrorNoPrefix` case.
   
   ## References
   
   - Similar fix in Valkey: 
[CVE-2025-67733](https://github.com/valkey-io/valkey/security/advisories/GHSA-p876-p7q5-hv2m)
 — replaced `addReplyErrorSdsEx` with `addReplyErrorSdsExSafe` which strips 
control characters
   - Related: [RESP protocol specification](https://redis.io/topics/protocol)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to