This is an automated email from the ASF dual-hosted git repository.
jihuayu pushed a commit to branch unstable
in repository https://gitbox.apache.org/repos/asf/kvrocks.git
The following commit(s) were added to refs/heads/unstable by this push:
new 27a6d8a78 fix(scripting): sanitize lua error replies (#3494)
27a6d8a78 is described below
commit 27a6d8a780d11f1e88ef2292114a26604bf049ce
Author: 纪华裕 <[email protected]>
AuthorDate: Wed May 20 10:54:40 2026 +0800
fix(scripting): sanitize lua error replies (#3494)
fix https://github.com/apache/kvrocks/issues/3493
Lua's error return poses an injection risk; see issues for details.
I used codex gpt-5.5 to fix it.
---
src/storage/scripting.cc | 12 +++++++++++-
tests/gocase/unit/scripting/scripting_test.go | 11 +++++++++++
2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/src/storage/scripting.cc b/src/storage/scripting.cc
index d1175b04e..49727b112 100644
--- a/src/storage/scripting.cc
+++ b/src/storage/scripting.cc
@@ -60,6 +60,16 @@ enum {
namespace lua {
+namespace {
+
+std::string SanitizeErrorMessage(std::string_view message) {
+ std::string sanitized(message);
+ std::erase_if(sanitized, [](char c) { return c == '\r' || c == '\n'; });
+ return sanitized;
+}
+
+} // namespace
+
lua_State *CreateState() {
lua_State *lua = lua_open();
LoadLibraries(lua);
@@ -1295,7 +1305,7 @@ std::string ReplyToRedisReply(redis::Connection *conn,
lua_State *lua) {
lua_rawget(lua, -2);
t = lua_type(lua, -1);
if (t == LUA_TSTRING) {
- output = redis::Error({Status::RedisErrorNoPrefix, lua_tostring(lua,
-1)});
+ output = redis::Error({Status::RedisErrorNoPrefix,
SanitizeErrorMessage(lua_tostring(lua, -1))});
lua_pop(lua, 1);
return output;
}
diff --git a/tests/gocase/unit/scripting/scripting_test.go
b/tests/gocase/unit/scripting/scripting_test.go
index f48492c9f..e1318977b 100644
--- a/tests/gocase/unit/scripting/scripting_test.go
+++ b/tests/gocase/unit/scripting/scripting_test.go
@@ -90,6 +90,17 @@ func TestScripting(t *testing.T) {
require.Nil(t, r.Val())
})
+ t.Run("EVAL - Lua error reply strips embedded CRLF", func(t *testing.T)
{
+ c := srv.NewTCPClient()
+ defer func() { require.NoError(t, c.Close()) }()
+
+ require.NoError(t, c.WriteArgs("EVAL", "return
redis.error_reply('ERR injected\\r\\n+INJECTED\\r\\n')", "0"))
+ c.MustRead(t, "-ERR injected+INJECTED")
+
+ require.NoError(t, c.WriteArgs("PING"))
+ c.MustRead(t, "+PONG")
+ })
+
t.Run("Script return recursive object", func(t *testing.T) {
c := srv.NewTCPClient()
defer func() { require.NoError(t, c.Close()) }()