This is an automated email from the ASF dual-hosted git repository.

twice pushed a commit to branch 2.11
in repository https://gitbox.apache.org/repos/asf/kvrocks.git

commit efc67150a2866f32f64f28babf6e6c3612c0fc7e
Author: Twice <[email protected]>
AuthorDate: Tue Feb 4 11:37:29 2025 +0800

    fix(conn): detect and drop HTTP requests in connection (#2765)
    
    Co-authored-by: hulk <[email protected]>
---
 src/server/redis_connection.cc                  |  9 ++++-
 tests/gocase/unit/connection/connection_test.go | 46 +++++++++++++++++++++++++
 2 files changed, 54 insertions(+), 1 deletion(-)

diff --git a/src/server/redis_connection.cc b/src/server/redis_connection.cc
index 092df73d..d3de392a 100644
--- a/src/server/redis_connection.cc
+++ b/src/server/redis_connection.cc
@@ -385,10 +385,17 @@ void 
Connection::ExecuteCommands(std::deque<CommandTokens> *to_process_cmds) {
 
     auto cmd_s = Server::LookupAndCreateCommand(cmd_tokens.front());
     if (!cmd_s.IsOK()) {
+      auto cmd_name = cmd_tokens.front();
+      if (util::EqualICase(cmd_name, "host:") || util::EqualICase(cmd_name, 
"post")) {
+        LOG(WARNING) << "A likely HTTP request is detected in the RESP 
connection, indicating a potential "
+                        "Cross-Protocol Scripting attack. Connection aborted.";
+        EnableFlag(kCloseAsync);
+        return;
+      }
       if (is_multi_exec) multi_error_ = true;
       Reply(redis::Error(
           {Status::NotOK,
-           fmt::format("unknown command `{}`, with args beginning with: {}", 
cmd_tokens.front(),
+           fmt::format("unknown command `{}`, with args beginning with: {}", 
cmd_name,
                        util::StringJoin(nonstd::span(cmd_tokens.begin() + 1, 
cmd_tokens.end()),
                                         [](const auto &v) -> decltype(auto) { 
return fmt::format("`{}`", v); }))}));
       continue;
diff --git a/tests/gocase/unit/connection/connection_test.go 
b/tests/gocase/unit/connection/connection_test.go
new file mode 100644
index 00000000..267d23da
--- /dev/null
+++ b/tests/gocase/unit/connection/connection_test.go
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package connection
+
+import (
+       "fmt"
+       "net/http"
+       "testing"
+
+       "github.com/apache/kvrocks/tests/gocase/util"
+       "github.com/stretchr/testify/require"
+)
+
+func TestConnection(t *testing.T) {
+       srv := util.StartServer(t, map[string]string{})
+       defer srv.Close()
+
+       t.Run("HTTP requests will be dropped", func(t *testing.T) {
+               _, err := http.Get(fmt.Sprintf("http://%s";, srv.HostPort())) 
//nolint:bodyclose
+               require.Error(t, err)
+               require.True(t, srv.LogFileMatches(t, "HTTP request.*Connection 
aborted"), "should contain HTTP drop log")
+
+               c := srv.NewTCPClient()
+               err = c.Write("GET / HTTP/1.1\r\nHOST: example.com\r\n")
+               require.NoError(t, err)
+               _, err = c.ReadLine()
+               require.Error(t, err)
+       })
+}

Reply via email to